目录
一、Vue生命周期
1.1 介绍
又名:生命周期回调函数、生命周期函数、生命周期钩子
Vue在关键时刻帮我们调用的一些特殊名称的函数
生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的
生命周期函数中的this指向的是vm或组件实例对象
下图八个生命周期钩子(四对)
beforeCreate、created 是数据监测和数据代理的前后,不是vm创建前后,this不是vm
beforeMount、mounted 是挂载完毕之前和之后
beforeUpdate、updated 是更新之前和之后
beforeDestroy、destroyed销毁完毕之前和之后
对于beforeDestroy:我们应该做一些收尾性的工作(具体查看图)
1.2 挂载流程
beforeCreate、created 是数据监测和数据代理的前后,不是vm创建前后,this不是vm
执行完beforeCreate、created后Vue才开始解析模板,生成虚拟DOM存储在内种中,页面显示的内容不是解析后的内容
比如插值语法{{n}},在页面展示的还是{{n}},不会显示n的值
beforeMount、mounted 是挂载完毕之前和之后
beforeMount:此时页面呈现的内容Vue还没有编译,比如{{name}},就会呈现这个,并不会呈现name的值,当beforeMount执行完之后才会解析页面的内容
如下所示,在beforeMount执行完毕后创建了一个vm.$el选项并且替换掉了el选项。并且还在这一步将内存中的虚拟DOM转为真实DOM插入页面,转成$el之后往
mounted:此时模板已经解析完成
对于mounted:只要是一上来怎么怎么的,就写在这里面
上图中在created函数执行完毕后有一个选项,什么含义呢?
问我们时候有template选项,如果没有的话就选右边的选项
右边的意思是root所在的标签也会参与Vue的模板解析,整个root所在的div标签都算作模板,这就是“outerHtml as template”的含义
这里的template是指的在data中定义的属性选项并不是template标签
<div id="root" :x="n">
<h2 :style="{opacity}">欢迎</h2>
<button @click="stop">停止变换</button>
</div>
那template怎么写?
此时就会解析template的内容,将解析的内容覆盖带有root属性的div标签中(完全进行替换)
而且template中的内容只允许有一个根节点,所以用div包裹起来
const vm = new Vue({
//el: '#root',
template: `<div><h2 :style="{opacity}">欢迎</h2></div>`,
.....
}
1.3 更新流程
当“when data changes”数据改变的时候就可以走更新流程,走beforeUpdate函数
当执行到updated的时候,数据和页面已经是最新的了,二者保持同步
1.4 销毁流程
销毁后借助Vue开发者工具看不到任何信息
销毁后自定义事件会失效,但原生DOM事件依然有效
一般不会在beforeDestroy操作数据,因为即便操作数据,也不会触发更新流程
经历销毁流程的时候首先要经历"when vm.$destroy() is called",当vm实例身上的$destroy()方法被调用的时候执行销毁流程
只要我们调用vm.$destroy(),就会完全销毁一个vm实例
清理它与其他实例的连接:假如A组件连接了B组件、C组件,当销毁了A组件中vm实例后,A 与B组件断开连接,A与C组件断开连接
解绑它的全部指令:当执行vm.$destroy()命令后,点击按钮n的值也不会增加
<h2 v-text="n"></h2>
<button @click="add">点我n+1</button>
<button @click="bye">点我销毁vm</button>
解绑事件监听器:
这个地方说的解绑事件监听器,描述的是自定义的事件,而不是原生的DOM事件
下面不是自定义的事件(点击事件),依旧可以正常执行,只不过页面不变化了
methods:{
add(){
console.log("add")
this.n++
},
bye(){
console.log("bye")
this.$destroy
}
}
虽然我们vm实例销毁了,但是不影响放大的回调,点击“点我n+1”按钮,依然会调用add方法
在生命周期beforeDestroy与destroyed中间,会废掉watchers(监视)、子组件、自定义事件监听器,
而且在这个回调函数中修改data中的数据不会生效,但是依然可以调用data中的函数
如下所示
beforeDestroy{
console.log('beforeDestroy')
this.n=99
},
destroyed{
console.log('destroyed')
}
二、总结
2.1 常用生命周期函数
1. mounted:发送AJAX请求、启动定时器、绑定自定义事件、订阅消息等初始化操作
2. beforeDestroy:清楚定时器、解绑自定义事件、取消订阅消息等收尾工作
2.2 案例
将标题透明度由1-0循环
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title> 初识vue</title>
<!--引入vue 引入之后,全局就多了一个vue这个构造函数-->
<script type="text/javascript" src="../js/vue.js"></script>
</head>
<body>
<div id="root">
<!-- opacity与data中opacity重名,我们就可以直接这么写( opacity也是样式里面的一个属性 -->
<h2 :style="{opacity}">欢迎</h2>
<button @click="stop">停止变换</button>
</div>
</body>
<script type="text/javascript">
//阻止vue在启动时生成生产提示
Vue.config.productionTip=false
const vm= new Vue({
el:'#root',
data:{
// 从1到0,透明度逐渐升高,设置初始值为不透明
opacity:1,
},
methods: {
stop(){
// clearInterval(this.timer) 这样太温柔,我们还可以在页面root中修改值来更改透明度
// 我们如果光单纯的调用这个,定时器还是会不断的启动
// 这个地方vm虽然杀死了,但是听时期其实还在执行,为了让定时器不再启动,我们再调用beforeDestroy钩子函数,关闭定时器
// 这个地方是将vm自杀
this.$destroy()
}
},
// Vue完成模板的解析并把初始的真实DOM元素放入到页面后(挂载完毕后)调用mounted
// 这个地方只会调用一次
mounted(){
// 开启一个定时器
// 这个地方为什么写this.id?
// 因为我们要在stop关闭这个定时器,这里的this是vm,我们往vm中存了一个timer,这样我们就能在stop函数中调用了
// 这里命名的话,尽量避免选择id、key这种特殊的属性
this.timer = setInterval(()=>{
this.opacity -=0.01
if( this.opacity<=0)
vm.opacity=1
},16)
},
// 在销毁vm之前调用
// 为什么不把定时器销毁写在stop函数中?
// 刚刚我们再stop函数中是相当于将vm自杀,点击按钮后销毁
// 但是在以后的开发中,基本不会出现这种情况,更不会调用类似stop函数
// 所以我们使用beforeDestroy钩子函数,不论是自杀还是他杀,都会在杀之前调用
beforeDestroy() {
clearInterval(this.timer)
}
})
</script>
</html>