Vue中的生命周期

  • 什么是生命周期?
  • 这里我们用一个类比来引出生命周期:

1.类比如下:

  • 1. 人的一生(生命周期)
    时期 做的事情
    婴儿将要出生 做好接生准备
    婴儿出生了(重要时刻) 做身体检测,打疫苗,摆满月酒
    婴儿会说话了 叫爸爸,叫妈妈,会用语言沟通
    婴儿会走路了 可以进行自主的移动,可以去玩耍了
    ……… …….
    ……… …….
    将要死亡了(重要时刻)
    已经死亡了 生命周期结束

由此可见,一般来讲生命周期这个概念就是相当于在什么时期,做什么事(特定的时期做特定的事)

  • 2. Vue的生命周期(就相当于vm的一生,在特定的时候调用特定的函数)
    运行时期 要运行的函数
    将要创建 调用beforeCreate()函数
    创建完毕 调用created()函数
    将要挂载 调用beforeMount()函数
    挂载完毕(重要时刻) 调用mounted()函数 ====> [重要的钩子函数]
    将要更新 调用beforeUpdate()函数
    更新完毕 调用updated()函数
    将要销毁 调用beforeDestory()函数 ====> [重要钩子]
    销毁完毕 调用destoryed()函数

2.生命周期的概念:

  • Vue的生命周期就是vue实例从创建到销毁的全过程,也就是new Vue() 开始就是vue生命周期的开始。Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期。钩子函数是Vue生命周期中每个阶段对外开放让程序员操作Vue的接口。Vue有8个钩子函数。
    • 特性:
      • 1.又名:生命周期回调函数、生命周期函数、生命周期钩子。
      • 2.是什么:Vue在关键时刻帮我们调用的一些特殊名称的函数。
      • 3.生命周期函数的名字不可更改,但函数的具体内容是程序员根据需求编写的。
      • 4.生命周期函数中的this指向是vm 或 组件实例对象。

3.生命周期图解:

image

4.生命周期函数解析:

1.beforeCreate( 创建前 )

  • 这个时候,在实例被完成创建出来,el和data都没有初始化,不能访问data、method,一般在这个阶段不进行操作。

2.created( 创建后 )

  • 这个时候,vue实例中的data、method已被初始化,属性也被绑定,但是此时还是虚拟dom,真是dom还没生成,$el 还不可用。这个时候可以调用data和method的数据及方法,createf钩子函数是最早可以调用data和method的,故一般在此对数据进行初始化。

3.beforeMount( 挂载前)

  • 此时模板已经编辑完成,但还没有被渲染至页面中(即为虚拟dom加载为真实dom),此时el存在则会显示el。在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。

4.mounted( 挂载后)(重要节点)

  • 此时模板已经被渲染成真实DOM,用户已经可以看到渲染完成的页面,页面的数据也是通过双向绑定显示data中的数据。 这实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的躺在我们的内存中,一动不动。

5.beforeUpdate(更新前)

  • 更新前状态(view层的数据变化前,不是data中的数据改变前),重新渲染之前触发,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染。只有view上面的数据变化才会触发beforeUpdate和updated,仅属于data中的数据改变是并不能触发。

6.updated(挂载后)

  • 数据已经更改完成,dom也重新render完成。

7.beforeDestroy(销毁前)(重要节点)

  • 销毁前执行($destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等…’)

8.destroyed(销毁后)

  • 销毁后 (Dom元素存在,只是不再受vue控制),卸载watcher,事件监听,子组件。

5.代码解析:

<body>
<!-- 准备好一个容器-->
<div id="root" :x="n">
<h2 v-text="n"></h2>
<h2>当前的n值是:{{n}}</h2>
<button @click="add">点我n+1</button>
<button @click="bye">点我销毁vm</button>
</div>
</body>

<script type="text/javascript">
Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

new Vue({
el:'#root',
// template:`
// <div>
// <h2>当前的n值是:{{n}}</h2>
// <button @click="add">点我n+1</button>
// </div>
// `,
data:{
n:1
},
methods: {
add(){
console.log('add')
this.n++
},
bye(){
console.log('bye')
this.$destroy()
}
},
watch:{
n(){
console.log('n变了')
}
},
// 1.执行初始化前beforeCreate 这个生命周期的钩子函数无法进行如何的操作,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。可以理解为只是走一个流程
beforeCreate() {
console.log('beforeCreate()函数执行了')
},
// 2.created():这个时候,vue实例中的data、method已被初始化,属性也被绑定,但是此时还是虚拟dom,真实dom还没生成,$el 还不可用。这个时候可以调用data和method的数据及方法,created钩子函数是最早可以调用data和method的,故一般在此对数据进行初始化。
created() {
console.log('created()函数执行了')
},
//3.beforeMount():此时模板已经编辑完成,但还没有被渲染至页面中(即为虚拟dom加载为真实dom),此时el存在则会显示el。在这里可以在渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取。
beforeMount() {
console.log('beforeMount()函数执行了')
},
//4.mounted():此时模板已经被渲染成真实DOM,用户已经可以看到渲染完成的页面,页面的数据也是通过双向绑定显示data中的数据。 这实例创建期间的最后一个生命周期函数,当执行完 mounted 就表示,实例已经被完全创建好了,此时,如果没有其它操作的话,这个实例,就静静的躺在我们的内存中,一动不动。
mounted() {
console.log('mounted()函数执行了')
},
// 5.beforeUpdate():更新前状态(view层的数据变化前,不是data中的数据改变前),重新渲染之前触发,然后vue的虚拟dom机制会重新构建虚拟dom与上一次的虚拟dom树利用diff算法进行对比之后重新渲染。只有view上面的数据变化才会触发beforeUpdate和updated,仅属于data中的数据改变是并不能触发。
beforeUpdate() {
console.log('beforeUpdate()函数执行了')
},
// 6.updated():数据已经更改完成,dom也重新render(渲染)完成。
updated() {
console.log('updated()函数执行了')
},
// 7.beforeDestroy():销毁前执行($destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等…’)
beforeDestroy() {
console.log('beforeDestroy()函数执行了','删除了定时器,取消了绑定事件以及监听器')
},
// 8.destroyed():销毁后 (Dom元素存在,只是不再受vue控制),卸载watcher,事件监听,子组件。
destroyed() {
console.log('destroyed()函数执行了')
},
})
</script>

运行结果:

image
image
image

6.总结

  • 常用的生命周期钩子函数:
    • 1.mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
    • 2.beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。
  • 关于销毁Vue实例
    • 1.销毁后借助Vue开发者工具看不到任何信息。
    • 2.销毁后自定义事件会失效,但原生DOM事件依然有效。
    • 3.一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

这里用一个例子来总结

  • (要求标题:欢迎学习Vue,改标题随时间变化透明度也均匀变化,点击停止按钮销毁Vue实例对象)
    <!-- 准备好一个容器-->
    <div id="root">
        <h2 :style="{opacity}">欢迎学习Vue</h2>
        <button @click="opacity = 1">透明度设置为1</button>
        <button @click="stop">点我停止变换</button>
    </div>

    <script 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)
                // 给Vue设置一个定时器
                this.timer = setInterval(() => {
                    console.log('setInterval')
                    this.opacity -= 0.01
                    if(this.opacity <= 0) this.opacity = 1
                },16)
            },
            beforeDestroy() {
                // 消除定时器需要写在 beforeDestroy()函数中
                clearInterval(this.timer)
                console.log('vm即将驾鹤西游了')
            },
        })
    </script>

运行结果:

image

这篇博客引用了作者为”小小前端程序员“的文章
原文链接为:CSDN