vue 常用Api整理 2 - 生命周期函数
说明
每个 Vue 实例在被创建之前都要经过一系列的初始化过程。例如需要设置数据监听、编译模板、挂载实例到 DOM、在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,给予用户机会在一些特定的场景下添加他们自己的代码 原文
下边是一个官网的图例,描述了各个生命周期函数的执行次序
生命周期函数
所有的生命周期钩子自动绑定 this 上下文到实例中,因此可以通过其访问数据、运算等,下边会按照生命周期函数执行顺序来讲解
1. beforeCreate
实例初始化后,创建完成之前被调用
2. created
实例创建完成后被立即调用,这个时候还没有开始挂载 不能访问 $el
3. beforeMount
挂载开始之前调用,即将开始挂载
对比:对应 react
componentWillMount
在完成首次渲染之前调用 此时仍可以修改组件的状态
4. mounted
实例挂载之后调用,但是并不是所有子组件也都一起挂载完成,如果需要整个视图渲染完毕 可以使用
this.$nextTick(function () {})
对比:对应 react
componentDidMount
完成首次渲染之后调用, 可以在这里操作DOM
5. beforeUpdate
数据更新完成前调用,发生在虚拟DOM重新渲染和打补丁前,在这里进一步的更改状态,不会触发重新渲染
对比:对应 react
componentWillUpdate
接受状态的改变,进行渲染之前调用,不同的是 vue 中允许在这一步更改状态;而 react 则禁止,如果要更改状态要在 react 的componentWillReceiveProps
声明周期中进行
6. updated
更改数据重新渲染虚拟DOM后调用,在这里,组件DOM已经更新,可以执行依赖DOM的操作,但是应该避免在这里更改状态,与 mounted 一样,不能保证所有子组件都挂载完成,可以使用 this.nextTick(function () {})` 进行全部渲染完的操作
对比:对应 react
componentDidUpdate
完成渲染新的props或者state后调用,此时可以访问到新的DOM元素
7. beforeDestroy
实例销毁之前调用,在这一步,实例仍然可用
对比:对应 react
componentWillUnmount
组件销毁之前调用,做一些清理工作
8. destroyed
实例销毁之后调用
对比:react 中没有这个生命周期钩子
9. 其他
react 中有
componentWillReceiveProps
这个钩子,用来组件接受更新时调用,可以再次更新 props 或者 state, 在 vue 中虽然没有这个声明周期钩子,但是 vue 实例提供一个 watch 属性,可以用来监视状态改变,与componentWillReceiveProps
功能类似react 中有
shouldComponentUpdate
这个钩子,用来判断决定组件是否需要更新,以减少重新渲染,提升性能;在 vue 中组件是否需要更新,由 vue 框架主动判断,不在需要开发者在这个函数中操作了
export default {
name: 'HomeBasic',
data() {
return {
text: 'home-basic-container'
};
},
methods: {
handleClick() {
this.change();
},
change() {
// console.log('self change');
this.text = 'xxx';
},
destroyAll() {
this.$destroy();
}
},
watch: {
text() {
console.log('text change');
}
},
beforeCreate() {
/*
实例初始化后,创建完成之前被调用
*/
console.log('1. beforeCreate');
},
created() {
/*
实例创建完成后被立即调用,这个时候还没有开始挂载 不能访问 $el
*/
// this.text = 'cbd'; // 更改状态有效
// console.log(this.$el); // undefined
console.log('2. created');
},
beforeMount() {
/*
挂载开始之前调用,即将开始挂载
*/
console.log('3. beforeMount');
},
mounted() {
/*
实例挂载之后调用,但是并不是所有子组件也都一起挂载完成
*/
this.$nextTick(function () {
console.log('4. mounted nextTick');
});
console.log('5. mounted');
},
beforeUpdate() {
/*
数据更新完成前调用,发生在虚拟DOM重新渲染和打补丁前,在这里进一步的更改状态,不会触发重新渲染
*/
console.log('6. beforeUpdate');
if (this.text) {
this.text = 'beforeUpdate';
}
},
updated() {
/*
更改数据重新渲染虚拟DOM后调用
*/
this.$nextTick(function () {
console.log('7. updated nextTick');
});
console.log('8. updated');
},
beforeDestroy() {
/*
实例销毁之前调用,在这一步,实例仍然可用
*/
console.log('9. beforeDestroy');
},
destroyed() {
console.log('10. destroyed');
}
};
/*
1. beforeCreate
2. created
3. beforeMount
5. mounted // this.$nextTick(fn) 会在 所有子组件挂在后执行
4. mounted nextTick
// 手动触发状态更改
text change
6. beforeUpdate // 在 beforeUpdate 中可以更改状态,不会触发重复渲染
text change
6. beforeUpdate // 如下可以看到 只是重新走了一遍 update 不会无限循环下去
8. updated(2)
7. updated nextTick(2)
*/