一、生命周期的基础知识
Vue.js 的组件实例有一个完整的生命周期,包含多个阶段,每个阶段都有一个相应的钩子函数可以用于执行相应的操作。以下是 Vue.js 的生命周期图示:
beforeCreate() {
// 在实例初始化之后,数据观测(data observer)和 event/watcher 事件配置之前被调用。
},
created() {
// 在实例创建完成后被立即调用
},
beforeMount() {
// 在挂载开始之前被调用--即将模板编译成虚拟 DOM,并在将其渲染到 DOM 之前执行。
},
mounted() {
// 实例挂载之后调用--将页面渲染完毕;
},
beforeUpdate() {
// 数据更新时调用,但是并未渲染新数据,这里适合拿旧数据和准备更新的数据做对比操作。
},
updated() {
// 在数据更新且模板重新渲染之后调用。
},
beforeDestroy() {
// 实例销毁之前调用--可以在这里进行解绑事件、销毁定时器、取消监听等等操作。
},
destroyed() {
// 实例销毁之后调用--一般是清理计时器等东西。
}
总之,Vue.js 的生命周期分为 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy 和 destroyed 等阶段,每个阶段都会有对应的钩子函数。
二、生命周期详解
1. beforeCreate 阶段
顾名思义,beforeCreate 阶段是在实例被创建之前调用的钩子函数,此时实例还没有被创建,所以也就无法访问到 data 和 methods 等实例属性。
beforeCreate() {
// 在实例被创建之前调用的钩子函数,此时实例还没有被创建,所以也就无法访问到 data 和 methods 等实例属性。
// 此时定义的 data 属性、methods 等都不会生效。
}
2. created 阶段
created 阶段是在实例被创建之后调用的钩子函数,此时已经可以访问到 data 和 methods 等实例属性,但尚未生成真正的 DOM。
created() {
// 在实例创建完成后被立即调用,此时已经可以访问到 data 和 methods 等实例属性,但尚未生成真正的 DOM。
// 比如可以在此时进行异步请求数据,操作数据等等。
}
3. beforeMount 阶段
beforeMount 阶段是在模板编译成虚拟 DOM,并在将其渲染到 DOM 之前执行的钩子函数,此时已经可以访问到 DOM 树,但是还没有渲染出来。
beforeMount() {
// 此时已经可以访问到 DOM 树,但是还没有渲染出来,可以在此时进行一些数据的处理和初始化操作,但是不要对已处理过的数据进行多次操作。
}
4. mounted 阶段
mounted 阶段是在模板被渲染成 DOM 之后调用的钩子函数,此时组件已经渲染完毕,DOM 中元素已经可以被访问到。
mounted() {
// 在模板被渲染成 DOM 之后调用,此时组件已经渲染完毕,DOM 中元素已经可以被访问到,常见使用场景比如向后台请求数据渲染页面,声明周期后,访问虚拟dom,可能需要等dom渲染完成才能访问,
// 可通过 this.$nextTick() 等待模板渲染完毕之后执行操作。
}
5. beforeUpdate 阶段
beforeUpdate 阶段是在数据更新时调用的钩子函数,但是此时并未渲染新数据,适合拿旧数据和准备更新的数据做对比操作。
beforeUpdate() {
// 数据更新时调用,但是并未渲染新数据,适合拿旧数据和准备更新的数据做对比操作。
// 也可以在此时对数据进行修改,但是应该避免无限更新。
}
6. updated 阶段
updated 阶段是在数据更新且模板重新渲染之后调用的钩子函数,此时可以访问新的 DOM 元素和更新之后的数据。
updated() {
// 在数据更新且模板重新渲染之后调用,可以访问新的 DOM 元素和更新之后的数据,但应该避免使用无限循环的操作,以免影响性能。
}
7. beforeDestroy 阶段
beforeDestroy 阶段是在实例销毁之前调用的钩子函数,此时组件实例仍然可以访问。
beforeDestroy() {
// 在实例销毁之前调用,一般是解除事件监听、定时器等等。
}
8. destroyed 阶段
destroyed 阶段是在实例销毁之后调用的钩子函数,此时组件实例已被完全销毁。
destroyed() {
// 实例销毁之后调用,一般用于清理计时器等。
}
三、生命周期常见错误的解决方案
1. created 阶段使用 $refs
在 created 阶段使用 $refs 来操作 DOM 元素会报错,因为此时模板还未渲染成真正的 DOM,$refs 中并没有对应的 DOM 元素。
解决方案:在 mounted 阶段使用 $refs 操作 DOM 元素。
2. watch 与 computed 属性
watch 和 computed 是 Vue.js 中的两个重要的属性。watch 属性是用来监听数据变化的,而 computed 属性是用来计算数据的。在 watch 中计算数据或在 computed 中修改数据都是不允许的。
解决方案:在 computed 中计算数据,在 watch 中监听数据变化。
3. destroyed 钩子中的数据清理
在 destroyed 钩子中进行数据清理时,因为此时组件已经销毁,所以不能再访问组件中的 data 属性,清理操作也就无法进行。
解决方案一:在 beforeDestroy 钩子中进行数据清理。
解决方案二:建议采用 aminated 和 transition 进行操作,对组件进行卸载切换时,即使在组件已经被销毁的情况下,也可以通过 aminated 和 transition 组件实现一些操作。
四、总结
Vue.js 的生命周期是 Vue.js 组件中非常重要的一个部分。在 Vue.js 组件中,每个实例都有一个完整的生命周期,包含多个阶段,每个阶段都对应一个钩子函数,可以在不同的阶段中做出相应的操作。学好 Vue.js 的生命周期,可以更好地进行 Vue.js 应用程序的开发。