环境:vue@2.6.10
vue 有八个生命周期钩子函数,这在 vue 官方文档中也是有写到,我们可以在钩子函数中做一些我们想要的操作,但是选择哪个钩子函数确实是很头疼的事,比如:进入一个组件时,我们要做一些初始化的获取数据操作,是选择 created 还是 mounted 钩子呢?
下面我们先来看代码和输出结果:
<div id="app">
<p>{{message}}</p>
</div>
var app = new Vue({
data: {
message: "hy learning vue lifecycle"
},
beforeCreate() {
console.group('beforeCreate 创建前状态===============');
console.log("%c%s", "color:red", "$el :" + this.$el); //undefined $el vue 实例使用的根 DOM 元素
console.log("%c%s", "color:red", "$data : " + this.$data); //undefined $data vue 实例观察的数据对象,vue 实例代理了对其 data 对象属性的访问
console.log("%c%s", "color:red", "message :" + this.message); //undefined
},
created() {
console.group('created 创建完毕状态===============');
console.log("%c%s", "color:red", "$el :" + this.$el); //undefined $el vue 实例使用的根 DOM 元素
console.log("%c%s", "color:red", "$data : " + this.$data); //已被初始化 $data vue 实例观察的数据对象,vue 实例代理了对其 data 对象属性的访问
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
},
beforeMount() {
console.group('beforeMount 挂载前状态=================');
console.log("%c%s", "color:red", "$el :" + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "$data :" + this.$data); //已被初始化
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
},
mounted() {
console.group('mounted 挂载结束状态================');
console.log("%c%s", "color:red", "$el :" + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "$data :" + this.$data); //已被初始化
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
},
beforeUpdate() {
console.group('beforeUpdate 更新前状态=================');
console.log("%c%s", "color:red", "$el :" + this.$el.innerHTML); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "$data :" + this.$data); //已被初始化
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
},
updated() {
console.group('updated 更新完成状态=================');
console.log("%c%s", "color:red", "$el :" + this.$el.innerHTML); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "$data :" + this.$data); //已被初始化
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
},
beforeDestroy() {
console.group('beforeDestory 销毁前状态=================');
console.log("%c%s", "color:red", "$el :" + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "$data :" + this.$data); //已被初始化
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
},
destroyed() {
console.group('destoryed 销毁完成状态=================');
console.log("%c%s", "color:red", "$el :" + this.$el); //已被初始化
console.log(this.$el);
console.log("%c%s", "color:red", "$data :" + this.$data); //已被初始化
console.log("%c%s", "color:red", "message :" + this.message); //已被初始化
}
}).$mount('#app')
输出结果为:
我们可以看到,在 Vue 创建实例的过程中:
在 beforeCreate 钩子时,Vue 实例化事件以及生命周期钩子函数,我们输出不到 $data 以及 $el,$data 是 Vue 实例观察的数据对象,$el 是 Vue 实例使用的根 DOM 元素;
到 created 钩子时,获取到了 $data,以及 message 的值,说明此时实例创建完成;
在 beforeMount 中,我们先判断 Vue 实例有没有 el 选项,没有的话要去调用 vm.$mount(el) 方法手动开始编译页面,然后再判断有无 template 模版,有的话用 render 函数编译模版,没有的话就将外界的 HTML 当作模版去编译,例如下面的 p 标签就是
<div id="app">
<p>外界 HTML</p>
</div>
<script>
var app = new Vue({
el: '#app'
})
</script>
看上面的输出,此时我们能看到 $el 根元素有了,但是 p 标签中 message 还是表达式的状态,这是因为此时还是虚拟DOM。
进入 mounted 的钩子中就会将虚拟 DOM 挂载到 el 上
在 F12 console 中 我们输入 app.message = "change" 然后回车,我们能看到如下结果:
先触发 beforeUpdate 钩子函数,此时 message 还是 hy learning vue lifecycle ,而到了 updated 钩子函数,message 的值已经发生了改变
我们在 console 中 输入 app.$destroy(),能看到下面的输出
此时,我们再输入 app.message = "change" 时,是不会触发钩子函数了,因为 destroy 钩子执行完后就销毁了所有的生命周期钩子函数、子组件、以及为所有 data 属性添加的观察对象和监听对象