生命周期的概念
- 当前组件在创建到销毁经历的一系列过程,称之为生命周期。
生命周期的阶段
- 生命周期分为3个阶段,这三个阶段分别是: 初始化阶段 ,运行中阶段,销毁阶段。
- 初始化阶段:有4个钩子函数
- beforeCreate:在实例创建之前执行,数据未加载状态。
- created:在实例创建、数据加载后,能初始化数据,DOM 渲染之前执行。
- beforeMount:虚拟DOM已创建完成,在数据渲染前最后一次更改数据。
- mounted:页面、数据渲染完成,真实 DOM 挂载完成。
- 运行中阶段:有2个钩子函数
- beforeUpdate:重新渲染之前触发。
- updated:数据已经更改完成,DOM也重新render完成,更改数据会陷入死循环。
- 销毁阶段: 有2个钩子函数
- beforeDestroy:销毁前执行(实例仍然完全可用)。
- destroyed:销毁后执。
- 钩子函数:钩子函数就是options配置项中的一个方法,在特定的触发条件( 时机 )下会自动触发。
初始阶段
- 触发条件是自动的。
<body>
<div id="app">
{{msg}}
<Hello></Hello>
</div>
<template id="hello">
<h3>你是如何学的</h3>
</template>
</body>
<script>
Vue.component('Hello', {
template: '#hello',
data() {
return {
money: 2000
}
}
})
new Vue({
data: {
msg: '初始化操作'
}
}).$mount('#app')
</script>
-
beforeCreate:
- 组件即将创建,进行组件事件和生命周期的初始化。
- 项目中一般不使用。
- 有的开发者也会在这里进行数据请求。
beforeCreate() { console.log('data', this.money) console.log('真实DOM', document.querySelector('h3')) } //结果: //data undefined //真实DOM null
- 这个阶段:组件创建前
- data:data选项中的数据获取不到
- RDOM:拿不到
- 项目中: 没什么用
- 但是这个阶段是一个对事件和生命周期的准备阶段,也是必不可少的
-
created
- 组件创建完成
- 项目中:
1) 异步请求接口数据
2) 数据修改
created() { this.money = 10000; console.log('data', this.money); console.log("真实DOM", document.querySelector('h3')); } //结果 //data 10000 //真实DOM null
- 这个阶段:
- data :数据能获到
- RDOM :拿不到
- 项目中:
数据的修改
异步数据请求
-
beforeMount
- 组件即将挂载。
- 判断根实例组件是否有el选项,如果没有,那么手动挂载,判断根实例组件中的其他子组件是否有template选项,如果没有,那么使用outerHTML插入。
- 项目中:
1) 异步请求接口数据
2) 数据修改
beforeMount() { this.money = 20000; console.log('data', this.money); console.log("真实DOM", document.querySelector('h3')); } //结果 //data 20000 //真实DOM null
- 这个阶段:
- data :数据能获到
- RDOM :拿不到
- 项目中:
数据的修改
异步数据请求
-
mounted:
- 组件挂载结束
- 使用真实DOM替换VDOM
- 项目中
- 异步请求接口数据
- 数据修改
- 真实DOM操作可以了( Vue一般情况下不要直接操作真实DOM, 一般可以进行第三方库的实例化(静态数据渲染来的)
mounted() { document.querySelector('h3').style.background = 'red' console.log('data', this.money) console.log('真实DOM', document.querySelector('h3')) } //结果 //h3标签变红色 //data 20000 //真实DOM <h3 style="background: red;">你是如何学的</h3>
- 这个阶段:
- data: 可以获得数据
- RDOM: 拿到了
- 项目中:
- 数据修改
- 异步数据请求
- 真实DOM操作可以了( Vue一般情况下不要直接操作真实DOM, 一般可以进行第三方库的实例化(静态数据渲染来的))
- 初始阶段总结(在项目中的使用情况):
- 数据请求:created
- 数据修改:created beforeMount mounted
- DOM操作: mounted
运行阶段
- 触发条件是: 当data选项中的数据发生改变时。
-
beforeUpdate
- 内部操作 :VDOM生成和diff的对比
- 表示组件即将更新,vdom --diff–>vdom的不同(patch对象)
- 这个阶段:
- data: 拿到了
- RDOM:获得
- 这个阶段进行的是vdom的生成和diff算法的对比,都是内部进行的,我们在项目中可以不使用。
-
updeted
- RDOM已经生成,可以进行异步数据请求得到的dom渲染的第三方库实例化。
- 组件更新结束,通过render函数将VDOM渲染成了真实DOM,然后驱动vue进行视图更新。
- 动态数据的渲染,进行dom操作( 第三方库的实例化 )。
<body> <div id="app"> <Hello></Hello> </div> <template id="hello"> <div> <input type="text" v-model = "money"> <h3> {{ money }} </h3> </div> </template> </body> <script> Vue.component('Hello', { template: '#hello', data() { //除了根式 return { money: 2000 } }, beforeUpdate() { console.log('data', this.money) console.log('真实DOM', document.querySelector('h3')) }, updated() { document.querySelector('h3').style.background = 'blue' console.log('data', this.money) console.log('真实DOM', document.querySelector('h3')) } }) new Vue({ data: { msg: 'hello 1902' } }).$mount('#app') </script>
销毁阶段
- beforeDestory: 组件即将销毁,准备调用 $destroy() 方法
- destoryed: 组件销毁结束
- 这两个钩子函数没有什么去别,功能很相似
- 项目中: 这两个钩子函数都可以用来做善后,把一些计时器,第三方库实例化出来的实例。
- 组件销毁的两种方式:
- 使用$destroy()方法(内部销毁)。
缺点: 会将组件的模板也保留下来 - 使用开关销毁(外部销毁)。v-if 这种类型的销毁不会留有模板
- 使用$destroy()方法(内部销毁)。
methods: {
destory () {
this.$destroy()
}
},
beforeDestroy () {
console.log( 'beforeDestroy ')
},
destroyed () {
console.log( 'destroyed')
}