文章目录
- 生命周期引入
- 挂载流程
- 更新流程
- 销毁流程
- 生命周期总结
生命周期引入
生命周期
:- 又名:生命周期回调函数、生命周期函数、生命周期钩子。
- 是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
- 生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
- 生命周期函数中的this指向是 vm 或 组件实例对象。
代码如下:
欢迎学习Vue
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
opacity:1
},
methods: {},//通过外部的定时器实现(不推荐)
setInterval(() => {
vm.opacity -= 0.01
if(vm.opacity <= 0) vm.opacity = 1
},16)
注意:
- {opacity}使用了对象的简写形式
- 因为定时器在vm的外面,所以我们要获取opacity就可以通过数据代理从vm上获得
- 因为小数的运算在js中是不准确的,所以我们没有写成vm.opacity === 0,而是写成vm.opacity <= 0
此时我们就可以借助生命周期函数。在Vue完成模板的解析并把真实DOM全部
挂载
到页面上完毕之后,会调用一个mounted()函数,我们可以借助它来完成这个案例:挂载
就是第一次把真实DOM放入到页面中
欢迎学习Vue
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
opacity:1
},
methods: {},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
setInterval(() => {
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
})//通过外部的定时器实现(不推荐)
/* setInterval(() => {
vm.opacity -= 0.01
if(vm.opacity <= 0) vm.opacity = 1
},16) */
mounted中Vue已经把它的this维护成了vm。所以上面的代码中使用箭头函数的时候,this往外寻找就是vm。挂载流程 下图中红圈mounted之前的部分都属于挂载部分。
红色圆框对应着生命周期函数
文章图片
其中有几个注意点:
文章图片
这个地方的create不是指的vm创建,而是数据监测、数据代理的创建
文章图片
此处是可以进行DOM操作的,页面的效果也会发生变化。但是紧随其后
文章图片
也就是说不管你此时如何操作DOM,当Vue把虚拟DOM转为真实DOM之后,你原来操作的效果都会消失。
template是什么?
例如我们现在有一段代码:
当前的n值是:{{n}}
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
},})
我们可以借助template让容器里面什么都不写:
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
template:`当前的n值是:{{n}}
`,
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
},})
注意:
- template后面跟字符串
- 如果不想全写在一行就要使用模板字符串,否则报错
- Vue会直接把template当作模板执行后面的步骤(解析生成真实DOM·····)。
- template里面只能有一个根元素,所以我们把他用div包裹(不要使用标签去包裹,会报错)
- 注意:
在使用了template之后,我们的网页:
文章图片
不使用template:
文章图片
也就是说如果使用template,Vue会将整个绿色框里的东西替换掉整个红色框里的东西:
文章图片
更新流程
文章图片
在这一步骤中我们可以看到Vue将真实的DOM节点在$el中存了一份,再去插入到页面之中。为什么这么做呢?
在前面我们说过Vue在进行新的虚拟DOM和旧的虚拟DOM比较的时候,会出现有的元素可以复用的情况。既然要复用我们就要有这个之前的元素才能去复用,所以说这个地方要存一份备用。
文章图片
销毁流程
文章图片
当我们执行了vm.$destroy()之后,代表着Vue进入了销毁流程。不过我们要注意的是vm销毁了,但他的工作成果还在,也就是说页面还是正常显示的。只是说没有人帮我们继续管理DOM。
例如:
文章图片
注意:
①这里的其他实例代表的是组件
②解绑的是所有的自定义事件监听器,而原生的DOM事件监听器仍是有效的
当前的n值是:{{n}}
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
})
文章图片
当我们点击了销毁按钮之后,页面还是这样没有变。不过当我们再次去点击+1的时候页面是没有反应的,同时打开Vue开发者工具我们发现啥都没有了:
文章图片
文章图片
意思是说销毁监听,子组件,和事件监听器
文章图片
在beforeDestroy这一部分,图中的文字告诉我们data、methods、指令等都是可用的。我们可以试一下:
当前的n值是:{{n}}
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
beforeDestroy() {
console.log('beforeDestroy')
this.add()
},
destroyed() {
console.log('destroyed')
},
})
结果:
文章图片
结果我们发现add()确实可以用,但是页面并没有发生变化。也就是说在beforeDestroy这一阶段,所有对数据的修改不会再发生更新。
生命周期总结 生命周期函数一共是8个,我们可以将它们看作4对:
- 将要创建 / 创建完毕
- 将要挂载 / 挂载完毕
- 将要更新 / 更新完毕
- 将要销毁 / 销毁完毕
- beforeCreate() / created()
- beforeMount() / mounted()
- beforeUpdate() / updated()
- beforeDestroy() / destroyed()
文章图片
接下来我们在开头的案例上添加一个需求:添加一个按键,点击之后透明度变化停止。
代码如下:
欢迎学习Vue
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
opacity:1
},
methods: {
stop(){
clearInterval(this.timer)
}
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
})
为了能让methods中的stop方法能访问到定时器,我们可以把定时器添加到vm身上。当然使用变量提升也是可以的。如果我们再添加一个按钮:将透明度设置为1。代码如下:
欢迎学习Vue
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
opacity:1
},
methods: {
stop(){
clearInterval(this.timer)
}
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
})
我们发现在点击停止变换之后,在点击透明度变化为1的按钮仍然是奏效的。
我们可以使用另外一种暴力的方法停止变换,使用$destroy():
欢迎学习Vue
type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。new Vue({
el:'#root',
data:{
opacity:1
},
methods: {
stop(){
this.$destroy()
}
},
//Vue完成模板的解析并把初始的真实DOM元素放入页面后(挂载完毕)调用mounted
mounted(){
console.log('mounted',this)
this.timer = setInterval(() => {
console.log('setInterval')
this.opacity -= 0.01
if(this.opacity <= 0) this.opacity = 1
},16)
},
beforeDestroy() {
clearInterval(this.timer)
},
})
不要想着在stop中去关闭计时器,如果vm是因为其他原因销毁(也就是说不是通过点击按钮),那么stop也就不会被调用,计时器也就不会被关闭。所以最好是把关闭定时器的操作放在beforeDestroy()中。
销毁vm后定时器仍然是在计时的,我们可以在beforeDestroy()中把它关掉
其实还有3个钩子在生命周期图中并没有体现,他们在特定的场景中才会使用到,例如:路由切换。常用的生命周期钩子:
- mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
- beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
- 销毁后借助Vue开发者工具看不到任何信息。
- 销毁后自定义事件会失效,但原生DOM事件依然有效。
- 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。
推荐阅读
- Vue|Vue中的过滤器
- Vue|Vue核心?(内置指令)
- WEB|我的VUE 学习之路(下)
- Vue|Vue实现复制粘贴功能
- Axios|axios的配置对象说明(config)
- 笔记(Vue 2.0)
- vue|vue2.0面试篇
- HTML + CSS + JavaScript 实现打地鼠小游戏 闲暇时刻玩一玩 轻松丢烦恼~
- 自由飞翔|【新冠疫苗预约】Fiddler抓包新冠疫苗预约接口及脚本实现