一篇文章带你搞懂Vue的生命周期

1、引入生命周期

假设有这么一个案例,打开一个页面,上面显示的内容在不断地由清晰到模糊的变化,也就是说不断地改变透明度,应该如何实现这么一个案例呢?

1.1、搭建页面结构

<div id="root">
    <h2 :style="{opacity}">{
   
   {msg}}</h2>
</div>
<script>
    Vue.config.productionTip = false
    new Vue({
      
      
        el: '#root',
        data: {
      
      
            opacity: 1,
            msg: 'vue的生命周期'
        }
    })
</script>

在这里插入图片描述
一种很容易想到的思路是我们在外部开一个定时器,就像下面这样

    Vue.config.productionTip = false
    const vm = new Vue({
    
    
        el: '#root',
        data: {
    
    
            opacity: 1,
            msg: 'vue的生命周期'
        }
    })
    setInterval(() => {
    
    
        vm.opacity -= 0.01
        if(vm.opacity <= 0) vm.opacity = 1
    }, 16)

在这里插入图片描述
静态图不方便展示,但实际上是可以看到效果的。

但这样做的有不好的地方,我们在vue对象管理的外部写入了其他的脚本,而且还修改了vm中的属性,实际情况下,我们不会用vm来接收vue对象。

另一种思路是我们写一个回调函数

methods: {
    
    
    change() {
    
    
        setInterval(() => {
    
    
        	console.log('调用了定时器')
            this.opacity -= 0.01
            if(this.opacity <= 0) this.opacity = 1
        }, 16)
    }
}

由于一开始就需要显示效果,不能绑定时间来调用回调函数,所以在结构中用插值语法调用回调函数。

<div id="root">
    <h2 :style="{opacity}">{
   
   {msg}}</h2>
    {
   
   {change()}}
</div>

在这里插入图片描述
有一个十分鬼畜的事情是页面一直闪烁,并且调用了很多定时器,这是因为定时器会修改属性的值,属性一但被修改,就要重新解析模板,一旦重新解析模板,就要继续调用计时器,形成了一个恶性循环。

有什么解决方法呢?

我们设想只调用一次定时器,以后就不再调用了,也就是说只在一个时间点调用定时器,过了这个时间点就不会调用了。怎么控制好这个时间点呢,或者说在哪个时间调用呢?vue为我们提供了这么一个函数,代表特定的时间点mounted

mounted是一个属于vue对象的函数。

    Vue.config.productionTip = false
    new Vue({
    
    
        el: '#root',
        data: {
    
    
            opacity: 1,
            msg: 'vue的生命周期'
        },
        mounted() {
    
    
            setInterval(() => {
    
    
                console.log('调用了定时器')
                this.opacity -= 0.01
                if (this.opacity <= 0) this.opacity = 1
            }, 16)
        }
    })

在这里插入图片描述
需求得到了解决。

在这里说明一下,mounted调用的时机只有一次,也就是说他只在vue对象的生存时期只调用一次,像这样的函数,我们就叫作生命周期函数,它们组成了vue的生命周期

2、vue的生命周期函数

vue的生命周期函数又叫做生命周期钩子。

下面给一张图来展示vue的生命周期:
在这里插入图片描述
下面分阶段来解释vue的生命周期

2.1、挂载流程

beforeCreate

beforeCreate是第一个生命周期函数,这里的create,指的是创建数据代理,既然数据代理没有创建,则此时vue就无法获取到data中的属性,以及methods中的方法,我们可以举个例子,在beforeCreate中卡个断点。

<div id="root">
    <h2 v-text="n"></h2>
    <h2>当前的n值是:{
   
   {n}}</h2>
    <button @click="add">点我n+1</button>
</div>
<script type="text/javascript">
    Vue.config.productionTip = false //阻止 vue 在启动时生成生产提示。

    new Vue({
      
      
        el: '#root',
        data: {
      
      
            n: 1
        },
        methods: {
      
      
            add() {
      
      
                console.log('add')
                this.n++
            },
        },
        beforeCreate() {
      
      
            console.log('beforeCreate', this)
            debugger
        },
    })
</script>

在这里插入图片描述
在这里插入图片描述
此时的this指的是vue的实例对象。
55

开发者工具为黑色。

我们发现发现此时页面无法获取到n的值,并且add方法也无法执行,跳过断点后
在这里插入图片描述
在这里插入图片描述

一切正常,这也就验证了在beforeCreate阶段,我们无法获取到data中的属性,以及methods中的方法。

created

created这个阶段,数据代理已经创建完毕,可以获取到data中的属性,以及methods中的方法,依旧是断点方式验证,不要忘记删除之前的断点

       created() {
    
    
           console.log('created', this.n)
           debugger
       }

在这里插入图片描述
在这里插入图片描述
可以获取到data中的属性,但此时页面还没有解析。

beforeMount

在这个阶段,页面呈现出未解析的状态,此时可以修改Dom,但即便修改了,最终也不会奏效,因为接下来解析模板时,会替换Dom结构。

 beforeMount() {
    
    
     console.log('beforeMount')
     debugger
 }

在这里插入图片描述
Dom可以修改,放行之后不奏效
在这里插入图片描述

mounted

这是我们引入生命周期的时候用到的,在这一步,页面显示的是解析后的结构,并且对Dom的修改是有效的,但要尽量避免,此时可以进行一些初始化操作,如开启定时器,订阅一个消息等。

        mounted() {
    
    
            console.log('mounted')
            debugger
        }

在这里插入图片描述
至此,挂载流程结束。

2.2、更新流程

beforeUpdate

在这一阶段,数据已经发生了更新,但页面还是旧的,即数据还有页面没有同步

        beforeUpdate() {
    
    
            console.log('beforeUpdate', this.n)
            debugger
        }

在这里插入图片描述
点击n+1后,进入断点
在这里插入图片描述

控制台显示n值为2,但页面未更新,接着根据新数据更新Dom,完成Model和view的同步。

updated

在这一阶段,数据已经发生了更新,页面也是新的,即数据和页面同步

        updated() {
    
    
            console.log('updated')
            debugger
        }

点击加1后发现
在这里插入图片描述

2.3、销毁流程

销毁流程我们需要通过vue中的$destroy来实现。

在这里插入图片描述
这里的实例指的是组件实例。

beforeDestroy

此时: vm中所有的: data、methods、指令等等,都处于可用状态,马上要执行销毁过程,一般在此阶段:关闭定时器、取消订阅消息.解绑自定义事件等收尾操作。

        beforeDestroy() {
    
    
            console.log('beforeDestroy')
        }

在这里插入图片描述
销毁vm后,点击add页面已经不发生变化了,输出add是因为一开始就绑定了事件,这个事件是原生的事件。

在这一阶段可以销毁引例中的定时器了。

			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)
				console.log('vm即将驾鹤西游了')
			},

destroyed在开发中用处不大,在这里就不过多赘述了。

3、vue的生命周期总结

常用的生命周期钩子:

  • mounted: 发送ajax请求、启动定时器、绑定自定义事件、订阅消息等【初始化操作】。
  • beforeDestroy: 清除定时器、解绑自定义事件、取消订阅消息等【收尾工作】。

关于销毁Vue实例

  • 销毁后借助Vue开发者工具看不到任何信息。
  • 销毁后自定义事件会失效,但原生DOM事件依然有效。
  • 一般不会在beforeDestroy操作数据,因为即便操作数据,也不会再触发更新流程了。

在这里借用Vue官网的一句话:你不需要立马弄明白所有的东西,不过随着你的不断学习和使用,它的参考价值会越来越高。

猜你喜欢

转载自blog.csdn.net/weixin_51624761/article/details/124616537