详解vue生命周期

编辑: admin 分类: javascript 发布时间: 2021-12-12 来源:互联网
目录
  • 为什么要理解生命周期
  • 什么是生命周期
  • 生命周期钩子函数
  • created和mounted
  • 钩子的一些实战用法
    • 1.异步函数
    • 2.Vue.nextTick对异步函数的结果进行操作
  • 总结

    为什么要理解生命周期

    用Vue框架,熟悉它的生命周期可以让开发更好的进行。

    如果只是单纯地知道vue里面的简单语法,你是可以实现对应的一些项目和对应的想法,但是如果一旦发生问题,我们就需要借助生命周期去寻找问题,甚至说有一些需求的话,你也通过生命周期的情况来定我们该把这个东西写在哪里。所以理解vue的生命周期还是很有必要的

    什么是生命周期

    Vue实例从创建到销毁的过程,就是生命周期。详细来说也就是从开始创建、初始化数据、编译模板、挂载Dom、渲染→更新→渲染、卸载等一系列过程。

    另外补充一点,Vue的实例,它是Vue框架的入口,可以理解为前端的ViewModel,它包含了页面中的业务逻辑处理、数据模型等,它也有自己的一系列的生命周期的函数钩子,辅助我们进行对整个Vue实例生成、编译、挂着、销毁等过程进行js控制。
    官网给出的生命周期图(翻译成中文)如下:

    在这里插入图片描述

    生命周期钩子函数

    生命周期钩子,就是生命周期事件的别名而已,生命周期钩子 = 生命周期函数 = 生命周期事件

    主要的生命周期函数分类:

    创建期间的生命周期函数:
    beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
    created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
    beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
    mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示

    运行期间的生命周期函数:
    beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
    updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!

    销毁期间的生命周期函数:
    beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
    destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解除绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。

    created和mounted

    在生命周期钩子函数中,最常用的应该就是created和mounted了。

    created:在模板渲染成html前调用,即通常初始化某些属性值,然后再渲染成视图。主要应用:调用数据,调用方法,调用异步函数
    mounted:在模板渲染成html后调用,通常是初始化页面完成后,再对html的dom节点进行一些需要的操作。

    在created的时候,视图中的html并没有渲染出来,所以此时如果直接去操作html的dom节点,一定找不到相关的元素
    而在mounted中,由于此时html已经渲染出来了,所以可以直接操作dom节点,

    其实两者比较好理解,通常created使用的次数多,而mounted通常是在一些插件的使用或者组件的使用中进行操作,比如插件chart.js的使用: var ctx = document.getElementById(ID); 通常会有这一步,而如果你写入组件中,你会发现在created中无法对chart进行一些初始化配置,一定要等这个html渲染完后才可以进行,那么mounted就是不二之选。

    钩子的一些实战用法

    1.异步函数

    这里我们用定时器来做异步函数

    <div id="app">
        <ul>
            <li v-for="(item,index) of list" key="index">{{item}}</li>
        </ul>
    </div>
    
    <script type="text/javascript">
        var app = new Vue({
            el:'#app',
            data:{
                list:['aaaaaaaa','bbbbbbb','ccccccc']
            },
            created:function(){
                consoloe.log('created异步:aaaaa');
                //异步获取数据
                // 因为是异步,就和我们ajax获取数据一样
                setTimeout(()=>{
                    this.list=['111','222','333','444'],
                    console.log('created异步:',document.getElementsByTagName('li').length);
                },0)
            },
            mounted: function () {
                console.log('mounted:',document.getElementsByTagName('li').length);
            },
            updated: function () {
                console.log('updated:',document.getElementsByTagName('li').length)
            },
        })
    </script>
    

    结果为:

    create: aaaaaaaa
    mounted: 3
    created异步函数: 3
    updated: 4

    解释:

    可以看到因为是在created的钩子中加入异步函数,所以函数的执行顺序为:

    ceated钩子,mounted钩子,异步函数,updated钩子(根据事件队列原理,只有在updated后,li才是真的DOM渲染为4个,所以异步函数中获取的li的个数时是没有变化的li的个数)。

    因为mounted获取到的是我们在Vue的data中设置初始值渲染的DOM,而我们是在异步函数中变化的list数据,所以mounted获取的li的个数为3。

    update函数是只要数据vue绑定的数据变化就会触发,所以最后执行,为4

    这是不是意味着可以直接在update函数中操作呢,其实不是,因为update函数是针对vue的所有数据的变化,而我们也有可能会有其他数据的变化。

    例如下面的例子:

    //我们利用异步函数改变了两次list,会发现update被触发了2次
    created:function(){
            //异步获取数据
            // 因为是异步,就和我们ajax获取数据一样
            setTimeout(()=>{
                 this.list=['111','222','333','444'],
                 console.log('created异步:',document.getElementsByTagName('li').length);
            },0)
            setTimeout(()=>{
                 this.list=['快乐大本营','脚踏实地','300033','天天向上','好好学习'],
                 console.log('created异步:',document.getElementsByTagName('li').length);
            },1000)
    },
    mounted: function () {
            console.log('mounted:',document.getElementsByTagName('li').length);
    },
    updated: function () {
            console.log('updated:',document.getElementsByTagName('li').length)
    },
    

    结果为:

    在这里插入图片描述

    2.Vue.nextTick对异步函数的结果进行操作

    我们想要改变数据时,各自触发各自的方法

    created:function(){
    //异步获取数据
    // 因为是异步,就和我们ajax获取数据一样
    
        //为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。
        setTimeout(()=>{
            this.list=['111','222','333','444'],
            console.log('created异步:',document.getElementsByTagName('li').length);
            this.$nextTick(function(){
                console.log("created$nextTick:",document.getElementsByTagName('li').length)
            });
        },0)
        setTimeout(()=>{
            this.list=['快乐大本营','脚踏实地','300033','天天向上','好好学习'],
            console.log('created异步:',document.getElementsByTagName('li').length);
            this.$nextTick(function(){
                console.log("created$nextTick:",document.getElementsByTagName('li').length)
            });
        },1000)
    },
    mounted: function () {
        console.log('mounted:',document.getElementsByTagName('li').length);
    },
    updated: function () {
      console.log('updated:',document.getElementsByTagName('li').length)
    },
    

    结果为:

    我们可以看到通过$nextTick我们可以对异步函数的结果进行各自的操作

    在这里插入图片描述

    总结

    本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注海外IDC网的更多内容!

    【原创作者:http://www.1234xp.com/jap.html 转载请说明出处】