1.生命周期钩子
函数名 |
说明 |
beforeCreate |
数据观测和内部事件初始化之前被调用,此时无法通过this访问data中的数据,也无法访问methods中的方法 |
created |
在这一步,数据观测和内部事件初始化已完成,可以访问通过this访问data中的数据和methods中的方法 |
beforeMount |
模版已被编译完成,但是编译后的模版未挂载到Dom中 |
mounted |
编译后的模版挂载到Dom后调用 |
beforeUpdate |
数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器 |
updated |
由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子 |
beforeDestroy |
实例销毁之前调用。在这一步,实例仍然完全可用 |
destroyed |
实例销毁后调用。该钩子被调用后,对应 Vue 实例的所有指令都被解绑,所有的事件监听器被移除,所有的子实例也都被销毁 |
activated |
组件专用,且组件需要被keep-alive包裹,当前组件被激活是调用,初次渲染也会执行 |
deactivated |
组件专用,且组件需要被keep-alive包裹,当前组件被停用时调用 |
2.模版的编译和渲染
- 这里主要是弄懂这个阶段Vue都干了什么
- 先判断是否通过el传入Dom,如果有,则自动执行渲染vm.$mounte(el),否则需要手动执行渲染vm.$mounte(el)
- 执行渲染时,在判断是否传入的template,如果有,则依次为模版进行渲染,没有的话,将el元素的内容作为模版进行渲染
- el属性有两个作用:一个是作为容器,将来存放被vue编译过的模版,第二个作用是作为备选的html模版供vue编译
- template属性是首选的html模版,它不存在的时候,则选中el属性对应的标签
- 不可在created()之前操作html模版,该操作可能导致模版被破坏
- mounted()钩子之后,原Dom会被完全替换,之前的监听Dom事件会失效
3.组件与生命周期
- 只有子组件全部更新完毕,才能触发父组件的mounted
- 切换子组件时,会触发父组件的beforeUpdate/updated函数
- 子组件内部更新不会触发父组件的beforeUpdate/updated函数
4. $nextTick(callback)
- Vue的Dom更新是异步操作,当数据发生改变时,浏览器兵分两路,,一路重新渲染相关Dom,一路继续执行后面的JS代码
- 如果后续的JS需要等到Dom更新完毕后才执行,有两个办法:延时定时器和$nextTick(cb)
- $nextTick:将回调延迟到DOM 更新循环之后执行
5.个人杂谈
- 当一个组件复用时,他们的methods/computed等都是共享的,但是生命周期却不是
- 如果需要进行防抖处理时,如果直接将防抖方法写到methods里面,会因为methods的共享性质,导致组件复用时,多个组件共用一个延时定时器,这个时候需要生命周期进行内处理,生命周期即使是组件复用,也是彼此独立的,生成的防抖方法因为是多次调用的结果,不会造成定时器共享
<body>
<div id="app">
<button @click="throttle_click">点我</button>
</div>
</body>
</html>
<script src="./vue.min.js"></script>
<script>
//节流函数
function throttle(cb,delay){
//记录上次回调执行时的时间戳
var prev = 0
//定义内部函数并返回,形成闭包,缓存prev
return function(){
//获取函数调用时的上下文
var context = this
//获取参数(事件对象)
var event = arguments[0]
//对比时间差 超过时间间隔则执行回调
if(Date.now() - prev >= delay){
//执行回调(绑定this,传递参数)
cb && cb.apply(context,event)
//更新prev
prev = Date.now()
}
}
}
var vm = new Vue({
el:"#app",
data(){
return {
throttle_click:null
}
},
created(){
this.throttle_click = throttle(this.onClick,500)
},
methods:{
onClick(){
console.log('click')
}
}
})
</script>