工作总结(2)

忙了一段时间,刚好有一堆可以总结的内容。这里我会先整理一下vuejs相关的内容。

关于vuejs的watch侦听器的用法

一般都知道vuejs的watch侦听器的用法,watch就是用来响应数据的变化的。数据的每一次变化,都会调用相应的侦听回调。比如:

1
2
3
4
5
6
7
8
// 官方演示代码的部分截取
watch: {
// 如果 `question` 发生改变,这个函数就会运行
question: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
},

但是上面这种侦听器只能侦听数据变化,换句话说,数据的第一次赋值是不会触发这个侦听方法的。所以这里就需要用到immediate这个属性了

1
2
3
4
5
6
7
8
9
10
11
// 上面部分官方演示代码的修改
watch: {
question: {
// 设置immediate为true之后,该回调将会在侦听开始之后被立即调用
immediate: true,
handler: function (newQuestion, oldQuestion) {
this.answer = 'Waiting for you to stop typing...'
this.debouncedGetAnswer()
}
}
},

还有一种情况是,需要侦听的数据是一个Object类型,上面的回调是不会被触发的,因为Vue的侦听默认情况下是handler 只监听这个Object对象它的引用的变化,不能侦听到Object内部属性的添加或删减,所以需要用到deep这个属性:

1
2
3
4
5
6
7
8
9
10
// 上面部分官方演示代码的修改,假定question是一个Object类型的数据
watch: {
question: {
// 设置deep为true之后,就能做深度侦听
deep: true,
handler: function (newQuestion, oldQuestion) {
// ...
}
}
},

vue-router路由懒加载(组件按需引用)

关于vue-router路由懒加载,应该是一个比较常规的操作,路由懒加载可以让项目在运行时减少不必要的代码加载,或者按运行时不同的需求加载部分代码,这样可以减少加载时间。

一开始用的方案是webpack的require.ensure()实现按需加载。webpack的中文文档叫代码分割(参考:https://webpack.js.org/api/module-methods/#requireensure )。

1
require.ensure(dependencies: String[], callback: function(require), chunkName: String)

这个方法传入三个参数:dependencies传入的是依赖的集合,在执行回调函数之前会声明集合中所有的依赖;callback传入的是回调函数,当所有依赖加载完毕之后,webpack就会执行这个回调函数;chunkName是提供给这个特定的 require.ensure() 的 chunk 的名称。通过提供 require.ensure() 不同执行点相同的名称,我们可以保证所有的依赖都会一起放进相同的 文件束(bundle)。

这样,就可以在vue-router中实现按需加载了:

1
2
3
4
5
6
7
8
9
10
11
const Login = resolve => {
require.ensure([], () => {
resolve(require('./views/Login/index.vue'))
})
}

const routes = [{
path: '/login',
name: 'login',
component: Login
}]

vue-router官方文档也提供了一种方案,写法上更简单:

1
2
3
4
5
6
/* 下面是一种特殊注释,可以在打包时说明打包到什么异步块中 */
const routes = [{
path: '/login',
name: 'login',
component: () => import(/* webpackChunkName: "login" */ './views/Login/index.vue')
}]

Vue.use

我们都知道vue.use是用于注册安装插件的,一般用的比较多的地方是一些UI框架的按需引入:

1
2
3
4
5
6
import {
Upload,
Progress
} from 'element-ui';
Vue.use(Upload);
Vue.use(Progress);

这里其实我只是想说一下,vue.use其实是可以链式使用的,因为源码中,vue.use在执行完之后会return this,而this指向的是vue本身,所以是可以链式使用的:

1
2
3
4
5
import {
Upload,
Progress
} from 'element-ui';
Vue.use(Upload).use(Progress);

多个UI框架组件冲突

一般其实不会出现这种情况,但难不了会出现,需要有解决方案。比如在一个项目中,有一部分页面是公众号H5,而其他页面是手机端页面,他们因为需求不同导致需要用不同UI框架的同名组件,这种情况下,可以尝试在引入时使用不同的命名:

1
2
3
4
5
6
7
8
9
import {
Dialog
} from 'vant';
Vue.use(Dialog);

import {
Dialog as muDialog
} from 'muse-ui';
Vue.use(muDialog);

延伸一下:如果是一个文件中有多个需要引入的方法,但同时这些方法都放在同一个文件中,在引入时可以直接写成import { * as xxx } from './xxx.vue,使用时就可以通过xxx.xx形式来使用。