一:生命周期的概念
生命周期是指从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期,它主要强调一个时间段。用一句话来概括就是:
Vue实例的生命周期: 从创建到销毁的整个过程
二:钩子函数
Vue框架内置函数,随着组件的生命周期阶段,自动执行
作用:特定的时间点执行特定的操作
三:vue2的生命周期
vue2的生命周期可以用一句话来划分就是:四大阶段,八个方法。
1.初始化阶段(Creation)
1.beforeCreate:这是生命周期所执行的第一个钩子函数,执行于组件实例被创建之初,data 和 methods 中的数据还没有初始化。
2.created:在实例创建完成后被调用,此阶段完成了数据观测 (data observer)、属性和方法的运算,以及 watch/event 事件的设置。但是此时还没有挂载到 DOM 上。
3.代码和效果如下:
<template>
<div>
<div id="test">{{name}}</div>
</div>
</template>
<script>
export default {
data() {
return {
name: '暴怒的代码'
}
},
beforeCreate() {
console.log('------------------初始化阶段------------------')
//这里data 和 methods 中的数据还没有初始化,所以输出的应该是undefined
console.log(`这是beforeCreate的执行:${this.name}`)
},
created() {
//这里数据已经初始化了,可以输出data中的内容
console.log(`这是Create的执行:${this.name}`)
//因为在created()中还没有渲染到DOM页面,所以在渲染前修改,选的数据是下面的内容
this.name = '在渲染到DOM之前就修改内容'
}
}
</script>
运行结果
2.挂载阶段(Mounting)
1.beforeMount:模板渲染,相关的 render 函数首次被调用,模板已经在内存中编译好了,但是尚未挂载到页面中去。
2.mounted:在实例被挂载到 DOM 后调用,真实DOM生成,此阶段完成了模板编译并且将实例挂载到 DOM 上。
3.代码和效果如下:
<template>
<div>
<div id="test">{{name}}</div>
</div>
</template>
<script>
export default {
data() {
return {
name: '暴怒的代码'
}
},
beforeCreate() {
console.log('------------------初始化阶段------------------')
//这里data 和 methods 中的数据还没有初始化,所以输出的应该是undefined
console.log(`这是beforeCreate的执行:${this.name}`)
},
created() {
//这里数据已经初始化了,可以输出data中的内容
console.log(`这是Create的执行:${this.name}`)
//因为在created()中还没有渲染到DOM页面,所以在渲染前修改,选的数据是下面的内容
this.name = '在渲染到DOM之前就修改内容'
},
beforeMount() {
console.log('------------------挂载阶段------------------')
//开始编译数据,但是当前数据只在内存中渲染,并没有真实的渲染到html页面上
console.log(`这是beforeMount的执行:${document.getElementById('test').innerText}`)
},
mounted() {
// 获取到数据,内存中的数据真实的挂载到页面中,Vue实例创建完成
console.log(`这是mounted的执行:${document.getElementById('test').innerText}`)
}
}
</script>
运行结果
3.更新阶段(Updating)
1.beforeUpdate:在数据更新之前被调用,发生在虚拟 DOM 重新渲染和打补丁之前,此阶段页面中渲染的数据还是旧的,但data里的数据是最新的,页面尚未和最新数据保持同步。
2.updated:在数据更新完成后被调用,实例的 DOM 已经更新。
3.代码和效果如下:
<template>
<div>
<div id="test">{{name}}</div>
<el-button @click="name='点击更新的内容'">更新内容</el-button>
</div>
</template>
<script>
export default {
data() {
return {
name: '暴怒的代码'
}
},
beforeCreate() {
console.log('------------------初始化阶段------------------')
//这里data 和 methods 中的数据还没有初始化,所以输出的应该是undefined
console.log(`这是beforeCreate的执行:${this.name}`)
},
created() {
//这里数据已经初始化了,可以输出data中的内容
console.log(`这是Create的执行:${this.name}`)
//因为在created()中还没有渲染到DOM页面,所以在渲染前修改,选的数据是下面的内容
this.name = '在渲染到DOM之前就修改内容'
},
beforeMount() {
console.log('------------------挂载阶段------------------')
//开始编译数据,但是当前数据只在内存中渲染,并没有真实的渲染到html页面上
console.log(`这是beforeMount的执行:${document.getElementById('test').innerText}`)
},
mounted() {
//获取到数据,内存中的数据真实的挂载到页面中,Vue实例创建完成
console.log(`这是mounted的执行:${document.getElementById('test').innerText}`)
},
beforeUpdate() {
console.log('------------------更新阶段------------------')
//页面上的数据还是以前的,内存中的数据是最新的
console.log(`这是beforeUpdate的执行,页面数据:${document.getElementById('test').innerText}`)
console.log(`这是beforeUpdate的执行,data数据:${this.name}`)
},
updated() {
//页面上的数据和内存中的数据都是最新的
console.log(`这是updated的执行,页面数据:${document.getElementById('test').innerText}`)
console.log(`这是updated的执行,data数据:${this.name}`)
}
}
</script>
运行结果
4.销毁阶段(Destruction)
1.beforeDestroy:在实例销毁之前调用,此时实例仍然完全可用,还没有真正的执行销毁,vue从运行阶段进入到销毁阶段。
2.destroyed:在实例销毁后调用,此阶段完成了实例的事件监听器和子组件的销毁,vue上所有的实例都不可以用了。
3.代码和效果如下:
<template>
<div>
<div id="test">{{name}}</div>
<el-button @click="name='点击更新的内容'">更新内容</el-button>
</div>
</template>
<script>
export default {
data() {
return {
name: '暴怒的代码'
}
},
render(h) {
return h('div', [
h('h1', this.name),
h('button', {
on: {
click: () => {
alert('点击了我')
}
}
}, 'Click me')
]);
},
beforeCreate() {
console.log('------------------初始化阶段------------------')
//这里data 和 methods 中的数据还没有初始化,所以输出的应该是undefined
console.log(`这是beforeCreate的执行:${this.name}`)
},
created() {
//这里数据已经初始化了,可以输出data中的内容
console.log(`这是Create的执行:${this.name}`)
//因为在created()中还没有渲染到DOM页面,所以在渲染前修改,选的数据是下面的内容
this.name = '在渲染到DOM之前就修改内容'
},
beforeMount() {
console.log('------------------挂载阶段------------------')
//开始编译数据,但是当前数据只在内存中渲染,并没有真实的渲染到html页面上
console.log(`这是beforeMount的执行:${document.getElementById('test').innerText}`)
},
mounted() {
//获取到数据,内存中的数据真实的挂载到页面中,Vue实例创建完成
console.log(`这是mounted的执行:${document.getElementById('test').innerText}`)
},
beforeUpdate() {
console.log('------------------更新阶段------------------')
//页面上的数据还是以前的,内存中的数据是最新的
console.log(`这是beforeUpdate的执行,页面数据:${document.getElementById('test').innerText}`)
console.log(`这是beforeUpdate的执行,data数据:${this.name}`)
},
updated() {
//页面上的数据和内存中的数据都是最新的
console.log(`这是updated的执行,页面数据:${document.getElementById('test').innerText}`)
console.log(`这是updated的执行,data数据:${this.name}`)
},
beforeDestroy() {
console.log('------------------销毁阶段------------------')
// 仍可以使用data与method方法
console.log(`这是beforeDestroy的执行:${this.name}`)
},
destroyed() {
// 已经销毁data与method方法
console.log(`这是destroyed的执行:${this.name}`)
},
}
</script>
运行结果
5.生命周期图解
6.两个特殊的生命周期钩子函数
vue2中有两个特殊的生命周期钩子函数,
- activated: keep-alive 组件专属,组件激活时调用该函数。
- deactivated:keep-alive 组件专属,组件被销毁时调用该函数。
总结
生命周期是vue2中一个很重要的知识点,同时也是面试中容易问到的高频面试点。熟练掌握了vue2的生命周期,可以让我们在项目开发过程中少走很多弯路,减少很多莫名其妙的bug,所以,希望本文能够对各位小伙伴有所帮助哦!
另:附上项目的Gitee源码,地址如下
vue2全家桶练习: 包含vue2下使用router路由跳转,vuex状态管理,inject注入,minixs混入,watch监听https://gitee.com/qianchen12138/vue2-family-bucket-practice
版权归原作者 暴怒的代码 所有, 如有侵权,请联系我们删除。