关于箭头函数。在组件的作用域内使用箭头函数,可以保证this始终指向组件实例

而生命周期函数、methods、watch函数则不应该使用箭头函数,因为箭头函数是和父级上下文绑定在一起的,this 不会是如你所预期的 Vue 实例,否则会莫名报错

Uncaught TypeError: Cannot read property of undefined


Uncaught TypeError: this.myMethod is not a function

关于data为什么是函数: 一个组件的数据在不同地方往往是多样化的,若data是个单纯的对象则会造成所有组件共同引用一个对象,这无疑是不合理的。而换成函数组件调用在初始化时可以保证return出来的是一个全新的副本。

关于计算属性。计算属性默认只有 getter,如果我们不注意去给计算属性赋值的话会报错:

[Vue warn]: Computed property “fullame” was assigned to but it has no setter.

必要时也可以提供一个 setter :

1
2
3
4
5
6
7
8
9
10
computed: {
name: {
get: function(){
return ...
},
set: function(newval){

}
}
}

那么什么时候我们会需要给计算属性赋值呢?比如说我们需要多针对表格做增删改查操作,这时候表格里面的数据是与model层双向绑定的,我们在修改某条数据的时候往往需要发送post请求成功之后才触发model层的改变,这时候我们可以把需要绑定的数据提到计算属性里面,计算属性设置get和set,视图层数据改变时出发set,然后把post请求放在set函数里面,成功之后再去修改model层,这样就不存在说先改变model层再发送请求改变数据库,后者model层改变了又存在请求失败的情况。

关于< keep-alive />
< keep-alive >包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们
< keep-alive >是一个抽象组件:它自身不会渲染一个DOM元素,也不会出现在父组件链中
当组件在< keep-alive >内被切换,它的activateddeactivated这两个生命周期钩子函数将会被对应执行
其中触发了异步操作的组件被缓存时事件仍然会执行并渲染。比如说< keep-alive >包裹了component1和component2,进入页面时,component1组件初始化请求了数据,在没有请求完成时我们就切换到了component2,这时候component1组件请求继续并在原有时间上完成渲染。

关于$set
我们都知道在model层对数据进行操作会引发视图层的改变,如arr.push、arr.concat、arr.shift等等。但其实不尽然,通过数组下标来改变值并不会触发视图层的渲染,同理通过obj.key来改变值也不会触发视图层的改变,这时候我们就需要用到 this.$set了。另外给对象新增属性视图层也不会检测到更新,因为Object.defineProperty递归劫持了data里面的所有属性,而在初始化的时候并不存在这个属性,而set方法则实现将这个属性添加到劫持队列里面。针对这个我们可以用Object.assgin( )来添加对个属性,因为触发了对象重新引用是肯定能触发M-V驱动的

修饰符。可以少敲几行代码,提高开发效率。

1
2
this.$set(this.arr, index, val)
this.$set(this.obj, key, val)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- 输入字符串转数字 -->
<input type="text" v-model.number="value">
<!-- 输入字符串去前后空格 -->
<input type="text" v-model.trim="value">
<!-- 监听鼠标按键,支持 left, right, middle -->
<button @click.left="onLeftClick">点击鼠标左键</button>
<button @click.right="onRightClick">点击鼠标右键</button>
<!-- 停止冒泡,阻止默认行为 -->
<button @click.stop.prevent="doThis"></button>
<!-- 键盘按下确认键,支持 keycode 和键别名 -->
<input @keyup.13="onEnter">
<!-- 只执行一次事件 -->
<button @click.once="doThis"></button>
<!-- 监听原生事件 -->
<el-button @click.native="doThis"></el-button>

资源释放。善用 destory 释放原生事件、第三方组件、全局事件总线等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import bus from 'event-bus'
import plugin from 'plugin'
export default {
// ...
created() {
bus.$on('hello', this.hello) // 注册全局事件
window.addEventListener('resize', this.onResize) // DOM 事件
plugin.init() // 第三方组件初始化
},
destoryed() {
bus.$off('hello', this.hello)
window.removeEventListener('resize', this.onResize)
plugin.destory()
}
}

关于v-for中的key值。使用v-for更新已渲染的元素列表时,默认用就地复用策略;列表数据修改的时候,他会根据key值去判断某个值是否修改,如果修改,则重新渲染这一项,否则复用之前的元素;通常我们遍历渲染一个数组时都会用下标来作为key值,但有时候这不是一种好的做法,比如说如果我们在数组的中间插入一项,那么插入项后面的元素都要重新渲染,最好的做法是选用数组项中唯一值来作为key值。

刷新当前路由: 点击当前高亮的路由并不会刷新 view,因为 vue-router 会拦截你的路由,它判断你的url并没有任何变化,所以它不会触发任何钩子或者是view的变化,解决对策:通过不断改变 url的 query 来触发view的变化。我们监听侧边栏每个 link 的 click 事件,每次点击都给 router push 一个不一样的query 来确保会重新刷新 view。

1
2
3
4
5
6
7
8
clickLink(path) {
this.$router.push({
path,
query: {
t: +new Date() //保证每次点击路由的query项都是不一样的,确保会重新刷新view
}
})
}

持续记录…