1. vue-cli 构建项目
官网地址
- 命令行
# 全局安装 vue-cli
$ npm install --global vue-clif
# 创建一个基于 webpack 模板的新项目
$ vue init webpack your-project-name
# 安装依赖,走你
$ npm install
# 进入项目
$ cd your-project-name
# 开发版本打包并运行
$ npm run dev
# 线上环境整个项目打包 生成 dist 可以直接部署到服务器上的文件夹
npm run build
2. 项目模板中使用 less 方法
原文地址
vue-cli 构建的项目默认是不支持 less 的,需要自己添加。
- 首先安装 less 和 less-loader ,在项目目录下运行如下命令
# npm安装
$ npm install less less-loader --save-dev
# 或者使用 yarn
$ yarn add less less-loader --dev
- 安装成功后,打开
build/webpack.base.conf.js
,在 module.exports = 的对象的 module.rules 后面添加一段:
module.exports = {
// 此处省略无数行,已有的的其他的内容
module: {
rules: [
// 此处省略无数行,已有的的其他的规则
{
test: /\.less$/,
loader: "style-loader!css-loader!less-loader",
}
]
}
}
- 最后在代码中的 style 标签中 加上 lang="less" 属性即可
- 之后在项目中测试是否成功
npm install less less-loader --save-dev
npm run dev
3. 在 router 下的路由文件里设置格式,将页面上路由中默认显示的 #/
给去掉
// 去掉路由中自带的 #/ 这种东西
mode: 'history',
- 需要注意的是使用了
history
之后需要在服务器部署时增加一些配置,具体方法插件下面官方写的配置方法
配置方法
4. 引入 jquery(可查相关教程文档)
- 安装
npm install jquery --save
- 配置
// 先在顶部引入 webpack
const webpack = require('webpack')
// plugins 中添加
new webpack.ProvidePlugin({
'window.jQuery': 'jquery', // 为了兼容其他的插件
jQuery: 'jquery',
$: 'jquery'
})
- 使用
5. :class 使用表达式
:class="{'想要改变的类名': 判断条件}
- 示例图片
6. DOM 事件修饰符
...
...
- 实例,如下图所示,添加
.self
点击了li 内部
的元素的话不会触发li
的 click 的点击事件
7. vue 使用 clipboard 实现复制功能
原文地址
- 安装依赖 clipboard.js
npm install clipboard --save
- 在需要使用的地方 require 引用
var clipboard = require('clipboard');
- 在页面加载后调用该方法即可
8. 解决 vue-resource 的跨越问题
我这里是 vue-cli 基于 webpack 的项目(注意:在修改了 proxyTable 之后需要在命令行中
npm run dev
重新运行下项目,否则是不会有效果的呀~)
- 错误信息
Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.
- 解决方法:
先找到对应的配置 js 文件中的 proxyTable
修改相应的配置
再在 main.js 中配置 vue-resource 的格式,不配置的话是无法向后台传递参数的
在 vue 文件中的使用
data 中绑定相应的静态配置
methods 增加相应的方法
mouted 在 data 数据挂载到实例对象的时候 ,请求页面数据,实现页面的正常显示
9. vue-router 单页之间如何在 js 中跳转
原文地址
- 三种写法
// 字符串
this.$router.push('/home/first')
// 对象
this.$router.push({ path: '/home/first' })
// 命名的路由
this.$router.push({ name: 'home', params: { userId: wise }})
10. vuex 实现组件之间数据的传递
根据 state 可以实时的获取到数据
原文地址
- 安装
npm install vuex --save
- 在 src 文件夹中新建一个 stroe 文件夹,并在目录下新建一个 index.js 文件(已有的话请忽略),index.js 文件编辑如下
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
let store = new Vuex.Store({
state: {
formData: {} // 企业提交数据表单对象
}
});
export default store;
- 在 src 目录下的 main.js 文件中引入 vuex 文件,并在实例化时添加配置
import Vue from 'vue';
import App from './App';
import router from './router';
import store from './store'; // 引入 vuex
Vue.config.productionTip = false;
Vue.http.options.emulateJSON = true;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, // 需要在添加
components: { App },
template: ' '
});
- 之后就可以直接在需要的组件中直接引用,引用具体示例如下
控制台成功输出
11. .eslintrc.js 文件 rules 增加设置
// add your custom rules here
rules: {
// allow async-await
'generator-star-spacing': 'off',
// allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
// 空格关闭
'no-tabs': 'off',
// 缩进为0
indent: 0,
'space-before-function-paren': 0, // 清除 function() {} 这样写报错的规则
quotes: 0 // 清除 "" 这样写报错的规则
}
12. vue 表单操作
- html 代码片段
- js 片段
var vm = new Vue({
el:'#app',
data:{
userData:{
companyName:'',
peopleNumber:'',
tellPlace:'',
tellCity:'',
tellFormat:'',
openFun:[],
Contacts:'',
contactTell:''
},
checkedNames:[]
},
methods:{
submit:function(){
var me = this;
var data = JSON.stringify(me.userData);
console.log(data);
}
}
});
- 浏览器器控制台在数据提交时的输出
- 总结
需要注意的一点是在复选框
checkbox
这种的组合时,需要在js
中将userData
中相应的属性openFun
的默认值写成数组,因为这个是数组类型的数据,还有就是在html
中写的时候需要注意每个checkbox
必须得有value
属性,且有相应值
13. 解决使用 vux 组件库时 与 rem 设置冲突带来的问题
- 思路
将之前 rem 计算的数值
html font-size: "100px"
,改到12px
,之后连锁的将 less 中计算和引用的的值也改下,之后就可以了,尽量做到少量的修改即可
- 将之前的 js 计算 rem 数值脚本修改相应的数值
改过之后的
- 修改 less
改过之后的
- 之后就可以是 rem 和 vux 基本正常了
14. 通过 watch 动态的监测路由跳转(跳转时)和 APP.vue 中设置 created 方法实时监测 path (刷新时),来实现 header 文字的改变
- header.vue
watch: {
'$route' (to, from) {
// 检测路由改变 header 内容
if (to.name === 'Index') {
this.$store.state.PageTitle = '预约领号';
this.$store.state.isShowBack = false;
} else if (to.name === 'PreferentialDescription') {
this.$store.state.PageTitle = '优惠说明';
this.$store.state.isShowBack = true;
} else if (to.name === 'RuleIntroduction') {
this.$store.state.PageTitle = '规则简介';
this.$store.state.isShowBack = true;
} else if (to.name === 'ReservationSuccess') {
this.$store.state.PageTitle = '预约排号';
this.$store.state.isShowBack = true;
}
}
}
15. vue-router spa (单页)需要的 nginx 配置,防止出现 404 的情况
官方文档
照着上方的图将代码复制至服务器的 nginx.config 配置文件即可
- ssh 远程登录服务器
ssh username@ipaddress
enter your password
- 查找服务器中的 nginx 相关目录,我这边是 nginx 服务器
whereis nginx
-
/etc/nginx
这个是 nginx 相关配置的目录 -
/usr/share/nginx
是静态文件的目录 - 进入 html 目录,这个就是默认的存放项目文件的目录
- 修改 nginx 默认的配置文件
# 首先进入配置文件目录
cd /etc/nginx
ls
# 查看配置文件
cat nginx.config
# 复制一份原始的配置文件
cp nginx.config nginx.config.back
# 按照上面 vue-router 的需求修改配置文件
vi nginx.config
# 进入编辑状态
I
# 修改文件
location / {
try_files $uri $uri/ /index.html;
}
# 之后保存并退出
esc
:
wq
# 再次查看是否已修改成功
cat nginx.config
# 重载 nginx 配置文件(必须重载,不然修改的是不会生效的!)
nginx -s reload
- 上面的步骤操作完成之后便解决了 vue-router spa 带来的刷新页面 404 的问题了,哦耶~
16. 与后台 API 进行通信时,Content-Type
请求文本格式未统一带来的问题
- 问题截图
后台返回 415 Unsupported Media Type
对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。
- 产生错误的原因:
这里使用的是
post
请求,后台的请求文本格式为Content-Type:application/json;charset=UTF-8
但是这里使用的是默认的Content-Type:application/x-www-form-urlencoded
所以造成的此次错误
- 解决方法
在提交数据之前使用
JSON
的stringify
方法将数据转换为 json 格式的文本即可,如下图所示
JSON.stringiy()
JSON.stringify() 方法是将一个JavaScript值(对象或者数组)转换为一个 JSON字符串,如果指定了replacer是一个函数,则可以替换值,或者如果指定了replacer是一个数组,可选的仅包括指定的属性。
17. 清除 .vue
文件在 vscode 编辑器中格式化时默认添加的分号和双引号的规则
参考地址
- 问题
因为
vue-cli
项目创建后会默认的增加.eslintrc.js
eslint 规则文件来帮助我们更好的统一代码的规范性,但是现在的趋势是省略javascript
代码书写时在末尾添加的分号,但是 vscode 编辑器因为装了vetur
这个插件,所以还是会像之前的那样默认追加,使得项目报 eslint 语法的错误,单双引号也是相同的问题
- 解决方法
先安装扩展插件
Prettier - Code formatter
之后在顶部菜单栏依次操作:【文件】->【首选项】->【设置】->【用户设置】
最后增加下面的规则代码片段
"prettier.singleQuote": true,
"prettier.semi": false
18. 之前的删掉了,等待更新中......
19. 给 vue
挂载全局方法
- 找到
main.js
文件进行编辑,这里以axios
为例演示
import Vue from 'vue'
import axios from 'axios'
Vue.prototype.axios = axios
- 使用方法 某个
.vue
文件的sccript
中如下编辑
Vue.axios.post('url', { name: '' })
.then(response => {
console.log(response)
})
.catch(response => {
console.log(response)
})
20. axios
不兼容 ie 的问题解决
- 问题描述
在 IE 浏览器下会报 “Promise”未定义" 的错误
- 资料
axios npmjs 地址
问题解决参考地址
- 解决方法
使用 babel-polyfill 这个包
- 装包
yarn add babel-polyfill --dev
- 之后在
main.js
文件中引入包即可
import 'babel-polyfill'
- 测试可兼容至 IE8+
- 更新 优化进阶 已经过测试
参考文章里面有详细的解释:babel-polyfill使用与性能优化
目的是为了打包出更小的体积,下图是使用新方法打包出的体积,用上面的方法打包出来是2.64MB
[图片上传失败...(image-1c4153-1542558418331)]
- 解决方法 将之前引入的
babel-polyfill
换成core-js/es6/promise
这个是vue-cli
脚手架就有的包无需再装了
import 'core-js/es6/promise' // 解决 axios 兼容 IE 问题
21. 组件封装,这里以 bootstrap 的 modal 模块为例
参考官方文档 -- 组件基础
参考官方文档 -- 组件注册
参考官方文档 -- props
- 先写组件,在
src -> components
目录下新建一个文件夹msgmodal -> index.vue
,编辑如下
- 在具体的
.vue
文件使用组件,方法如下,这里是用的动态绑定的方法传递属性的值
// script
import MsgModal from '@/components/msgmodal'
export default{
name:'App',
components: { MsgModal },
data () {
return {
// 弹窗信息 在执行操作时使用
modalMsg: ''
}
}
}
- 测试,已实现可以实时更新内容了
22. 在 router -> index.js
按需引入模块,优化 SPA
页面的性能
参考地址
- 源码
import Vue from 'vue'
import Router from 'vue-router'
import VueResource from 'vue-resource'
// import index from '@/index'
// import companyapply from '@/companyapply'
// import choosenumber from '@/choosenumber'
// import statelist from '@/statelist'
Vue.use(Router)
Vue.use(VueResource)
export default new Router({
// 去掉路由中自带的 #/ 这种东西
mode: 'history',
routes: [
{
path: '/',
name: 'index',
component: () => import('@/index')
},
{
path: '/companyapply',
name: 'companyapply',
component: () => import('@/companyapply')
},
{
path: '/choosenumber',
name: 'choosenumber',
component: () => import('@/choosenumber')
},
{
path: '/statelist',
name: 'statelist',
component: () => import('@/statelist')
}
]
})
23. 在 Vue
上挂载 vux
库中的 LoadingPlugin
组件
官方文档地址 - 该组件支持以plugin形式调用
main.js
// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import { LoadingPlugin } from 'vux' // 引入 looding 组件
import App from './App'
import store from './store' // 引入 vuex
import router from './router'
Vue.config.productionTip = false
Vue.http.options.emulateJSON = true
Vue.use(LoadingPlugin) // 挂载 loading 组件
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, // 需要在添加
components: { App },
template: ' '
})
-
.vue
文件中具体的使用示例:
// loading
this.$vux.loading.show({
text: '数据提交中
})
// 隐藏 loading
this.$vux.loading.hide()
24. 解决:使用 axios
默认发送的是 application/json;charset=UTF-8
这种格式的数据后台无法读取的问题
后台需要的是
application/x-www-form-urlencoded
这样的数据格式
参考地址
- 问题截图
- 需要的格式截图
-
解决方法
- 使用
qs
模块,转换数据格式
- 源码
import qs from 'qs' // 解决 axios 数据提交格式与后台不一致的问题 -> name=hehe&age=10 axios.post(postAPI,qs.stringify(postData)) .then(request => { console.log(request) }) .catch(error => { console.log(error) })
- 使用
25. 化繁为简的Watchers
原文地址
- 场景还原:
created(){
this.fetchPostList()
},
watch: {
searchInputValue(){
this.fetchPostList()
}
}
组件创建的时候我们获取一次列表,同时监听input框,每当发生变化的时候重新获取一次筛选后的列表这个场景很常见,有没有办法优化一下呢?
- 招式解析:
首先,在watchers中,可以直接使用函数的字面量名称;其次,声明immediate:true表示创建组件时立马执行一次。
watch: {
searchInputValue:{
handler: 'fetchPostList',
immediate: true
}
}
26. 父子组件通信 -- 子组件可以调用父组件的方法
- 实现思路
使用
this.$emit()
以下示例为分页组件,下面只是将主要的部分代码贴出
- 父组件