黑马程序员技术交流社区
标题: 【西安校区】【干货】详解vue生命周期 [打印本页]
作者: 逆风TO 时间: 2020-3-31 11:29
标题: 【西安校区】【干货】详解vue生命周期
生命周期定义每个vue实例在被创建之前都要经过一系列的初始化过程,这个过程就是vue的生命周期。详细来说,就是Vue实例从开始创建,初始化数据,编译模板,挂在dom->渲染,更新->渲染,卸载等一系列过程,我们称这是vue的生命周期,各个阶段有相对应的事件钩子。
钩子函数:当代码执行到特定阶段的时候会调用的函数,也是回掉函数。生命周期示意图
代码解析生命周期1.new Vue() 创建实例2.初始化事件和生命周期3.beforeCreate
代码:
[Java] 纯文本查看 复制代码
let vm = new Vue({
// 当前这个实例他的父亲是谁 儿子谁 有一套
beforeCreate(){
console.log(this);
console.log('---beforeCreate---');
},
data(){
return{
msg:'hello'
}
}
})
从打印出来的this,可以看到此时发布订阅 emit等vue原生API已经初始化完成。但是不能访问到data,computed,watch,methods上的方法和数据。这个钩子函数不能做业务逻辑,一般情况下这个钩子函数可以做的事情:在每个组建中增加一些特定的属性,例如混合。
4.初始化注入和校验5.created这个实例已经实现了数据劫持,把方法、计算属性 也都挂载到了实例,不能获取到真实的dom元素。不能访问到 ref属性内容未空数组。这个钩子函数可以发送axios请求把请求回来的数据保存到data中。
[Java] 纯文本查看 复制代码
let vm = new Vue({
beforeCreate(){
console.log(this);
console.log('---beforeCreate---');
},
created(){
console.log(this);
console.log('---created---');
debugger;
},
data(){
return{
msg:'hello'
}
}
})
6.beforemount接下来就是渲染,但是在渲染之前会先判断“是否有制定的el选项”,正常的写法:el:'app',另一种用:vm.$mount('app')
$mount 可以指定一个元素,不指定元素的话,内部会默认渲染到一个内存中的节点
[JavaScript] 纯文本查看 复制代码
let vm = new Vue({
beforeCreate(){
console.log('---beforeCreate---')
},
created(){
console.log(this)
console.log('---created---')
},
beforeMount(){
console.log('---beforeMount---')
},
data(){
return{
msg:'hello'
}
}
})
vm.$mount()
虽然渲染失败了,但是走到了beforeMount这个钩子函数,它的要求是要么有个template,或者有个render函数。 把两者中一个加上:
[JavaScript] 纯文本查看 复制代码
render(){
},
template:'<div>hello</div>',
验证一下我们之前没有指定el,渲染在内存中,我们把它挂载到页面中去。
[JavaScript] 纯文本查看 复制代码
vm.$mount()
console.log(vm.$el)
document.body.appendChild(vm.$el)
好处:可以把渲染好的元素插入到自己想要的节点中。
在生命周期流程图中,判读完el选项后,就会再判读是否有“指定的template选项”,是就将template编译到render函数中,没有则将el外部的HTML作为template 编译。什么叫做el外部的HTML?就是我们常用:
[Java] 纯文本查看 复制代码
<div id="app"></div>
vm.$mount('#app')
这个div就是el外部的HTML,再统一编译到render函数中。
[JavaScript] 纯文本查看 复制代码
let vm = new Vue({
beforeCreate(){
console.log('---beforeCreate---')
},
created(){
console.log(this)
console.log('---created---')
},
render(){
console.log('---render---')
},
template:'<div>hello</div>',
beforeMount(){
console.log('---beforeMount---')
},
data(){
return{
msg:'hello'
}
}
})
vm.$mount('#app')
console.log(vm.$el)
document.body.appendChild(vm.$el)
ocument.body.appendChild(vm.$el)复制代码
如果有了render就不会使用template,它内部会把template渲染成render方法,所以在挂载之前会调用render方法。优先级关系:render>template>out html
beforeMount 做的事情就是调用render方法,但是一般不会增加业务逻辑
7.mounted实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问。
[JavaScript] 纯文本查看 复制代码
let vm = new Vue({
beforeCreate(){
console.log('---beforeCreate---')
},
created(){
console.log(this)
console.log('---created---')
},
template:'<div>hello</div>',
beforeMount(){
console.log('---beforeMount---')
},
mounted(){
console.log('---mounted---')
console.log(vm.$el)
},
data(){
return{
msg:'hello'
}
}
})
vm.$mount('#app')
8.beforeupdatevue 更新方式是组件级别的,比如我们项目会有许多组件,在根组件中引用3个组件,其中一个组件更新重新渲染了(异步渲染),另外两个不会重新渲染。可以在这个钩子函数中,增加一些数据更新,不会导致试图多次更新。响应式数据更新时调用,发生在虚拟DOM打补丁之前。组件更新之前执行的函数。数据更新了,但是,vue(组件)对象对应的dom中的内部(innerHTML)没有变,所以叫作组件更新前。
[JavaScript] 纯文本查看 复制代码
<div id="app">{{msg}}</div>
<script>
let vm = new Vue({
beforeCreate(){
console.log('---beforeCreate---')
},
created(){
console.log(this)
console.log('---created---')
},
beforeMount(){
console.log('---beforeMount---')
},
mounted(){
console.log('---mounted---')
console.log(vm.$el)
},
beforeupdate(){
console.log('---beforeupdate---')
},
data(){
return{
msg:'10'
}
}
})
vm.$mount('#app')
</script>
数据是应用到视图上才会变化。
9.updated虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作.
这个钩子函数就不要再去更新数据,可能会发生死循环
[JavaScript] 纯文本查看 复制代码
updated(){
this.msg= Math.random();
console.log('---updated---')
},
更新后会重新渲染,同时再走一边rander方法
10.beforeDestroy实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例这个钩子函数一般做事件的移除、清空定时器
11.destory常见的销毁方式:手动( vm.$destory()移除所有的观察者 )、移除组件、路由切换实例销毁后调用,调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。视图并不会刷新,
转自链接:https://juejin.im/post/5e81e9e16fb9a03c3c350918
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |