美文网首页
浅谈vue的生命周期

浅谈vue的生命周期

作者: 刀刀小技 | 来源:发表于2019-02-02 10:23 被阅读0次

生命周期

在使用vue的过程中,对vue的生命周期的理解是最基础的开始,也许你不需要全部理解,但对其中最主要的几个阶段却要知之甚深,这是你项目中密切相关的。

周期图

image

这是一张vue官网上面展示的生命周期图,对每一个过程都做了罗列。

周期说明

所有的生命周期钩子函数会自动绑定this上下文到实例中,因此可以访问数据,对属性和方法进行运算。不能使用箭头函数来定义一个生命周期方法
如(created: () => this.fetch()),箭头函数绑定了父上下文,因此this与vue的实例不同,会显示未定义。

  • 1、beforeCreate

在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。

在这个阶段可以异步方式获取data数据,使用this.$nextTick或者setTimeout都行,当全执行完之后会执行里面的代码,获取需要的数据。

如果需要同步拿到数据,需要了解数据存放地点,在beforeCreate前,所有的options都会先存到vm.options中,在beforeCreate之后才会附到vm上,然后再触发created钩子,所以要想在这个时候拿到数据,那直接**this.options.data()["data"]**获取。

beforeCreate最好不要改动data里的数据,否则可能会出现无法监听的情况,模板中需要使用data进行渲染时,先给data默认的初始值,created之后再进行更改(如ajax)改成需要的值。

  • 2、created

组件实例创建完成,属性已绑定,但DOM还未生成,挂载阶段还没开始,$el属性还不存在。在这一步主要的工作为:调用数据,调用方法,调用异步函数。

在create函数里面是可以获取到data,调用Vue方法,可以获取到原本Html上直接加载出来的DOM,但是无法获取到通过挂载模板生成的DOM。比如v-for遍历的内容。在这一步通常会初始化某些属性值,比如通过异步函数获取数据更新data,然后再渲染成视图。

  • 3、beforeMount

在挂载开始之前被调用:render 函数或者模板首次被调用。

  • 4、mounted

el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。这个时候DOM会被渲染完成,初始的数据会被渲染完成,在这里才能获取到具体的DOM元素。

  • 5、beforeUpdate

数据更新时调用,发生在虚拟 DOM 重新渲染之前。 你可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程。 当我们更改Vue的任何数据,都会触发该函数。

  • 6、updated

由于数据更改导致的虚拟 DOM 重新渲染,在这之后会调用该钩子。 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态,因为这可能会导致更新无限循环。 该钩子在服务器端渲染期间不被调用。

  • 7、beforeDestroy

实例销毁之前调用。在这一步,实例仍然完全可用。

  • 8、destroyed

Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。

var vm = new Vue({
    el: '#vue_det',
    data: {
        info: "This Test"
    },
    beforeCreate: function() {
        console.group('beforeCreate 创建前状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data)); //undefined 
        console.log("%c%s", "color:red", "info: " + this.info)
    },
    created: function() {
        console.group('created 创建完毕状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el); //undefined
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data)); //已被初始化 
        console.log("%c%s", "color:red", "info: " + this.info); //已被初始化
    },
    beforeMount: function() {
        console.group('beforeMount 挂载前状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
        console.log(this.$el);
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data)); //已被初始化  
        console.log("%c%s", "color:red", "info: " + this.info); //已被初始化  
    },
    mounted: function() {
        console.group('mounted 挂载结束状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el); //已被初始化
        console.log(this.$el);
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data)); //已被初始化
        console.log("%c%s", "color:red", "info: " + this.info); //已被初始化 
    },
    beforeUpdate: function() {
        console.group('beforeUpdate 更新前状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
        console.log(this.$el);
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
        console.log("%c%s", "color:red", "info: " + this.info);
    },
    updated: function() {
        console.group('updated 更新完成状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
        console.log(this.$el);
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
        console.log("%c%s", "color:red", "info: " + this.info);
    },
    beforeDestroy: function() {
        console.group('beforeDestroy 销毁前状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
        console.log(this.$el);
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
        console.log("%c%s", "color:red", "info: " + this.info);
    },
    destroyed: function() {
        console.group('destroyed 销毁完成状态===============》');
        console.log("%c%s", "color:red", "el     : " + this.$el);
        console.log(this.$el);
        console.log("%c%s", "color:red", "data   : " + JSON.stringify(this.$data));
        console.log("%c%s", "color:red", "info: " + this.info)
    }
})

第一次运行,输出结果如下:


image

当在控制输入vm.info = "rewrite"对info进行更新时:

image
在beforeUpdate和updated里面 info的值都变为了'rewrite'

created和mounted区别

通过上面的说明可以理解两者的不同。通常created使用的次数多,而mounted通常是在html渲染完成后去获取或者更新某些DOM元素时使用,在mounted中通常会对插件或者组件进行使用。

var vm = new Vue({
    el: '#vue_det',
    template: "<ul><li id='name'>{{name}}</li><li>{{age}}</li></ul>",
    created: function() {
        this.name = "js"
        this.age = "12"
        var x = document.getElementById("name") //第一个命令台错误,这个时候模板页面还没有渲染完成
        console.log(x.innerHTML); // Cannot read property 'innerHTML' of null
    },
    mounted: function() {
        var x = document.getElementById("name") //第二个命令台输出的结果
        console.log(x.innerHTML); //js
    }
})

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

el选项的有无对生命周期过程的影响

系统会判断对象中有没有el选项,有el选项,则继续编译过程,没有el选项,则停止编译,也意味着暂时停止了生命周期,直到vm.$mount(el)

var vm = new Vue({
    el: '#vue_det',
    data: {
        info: "This Test"
    },
    beforeCreate: function() {
        console.log('调用了beforeCreat钩子函数')
    },
    created: function() {
        console.log('调用了created钩子函数')
    },
    beforeMount: function() {
        console.log('调用了beforeMount钩子函数')
    },
    mounted: function() {
        console.log('调用了mounted钩子函数')
    }
})
//控制台输出
/*
*调用了beforeCreat钩子函数
*调用了created钩子函数
*调用了beforeMount钩子函数
*调用了mounted钩子函数
*/

在el选项填写且正确的时候,生命周期将正常进行。

下面我们去掉el选项:

var vm = new Vue({
    data: {
        info: "This Test"
    },
    beforeCreate: function() {
        console.log('调用了beforeCreat钩子函数')
    },
    created: function() {
        console.log('调用了created钩子函数')
    },
    beforeMount: function() {
        console.log('调用了beforeMount钩子函数')
    },
    mounted: function() {
        console.log('调用了mounted钩子函数')
    }
})
//控制台输出
/*
*调用了beforeCreat钩子函数
*调用了created钩子函数
*/

可以看到,生命周期的钩子函数执行到created就结束了。

而当我们不加el选项,但是手动执行vm.$mount(el)方法的话,也能够使暂停的生命周期进行下去,如下所示:

var vm = new Vue({
    data: {
        info: "This Test"
    },
    beforeCreate: function() {
        console.log('调用了beforeCreat钩子函数')
    },
    created: function() {
        console.log('调用了created钩子函数')
    },
    beforeMount: function() {
        console.log('调用了beforeMount钩子函数')
    },
    mounted: function() {
        console.log('调用了mounted钩子函数')
    }
})
vm.$mount('#vue_det');
//控制台输出
/*
*调用了beforeCreat钩子函数
*调用了created钩子函数
*调用了beforeMount钩子函数
*调用了mounted钩子函数
*/

可以看到,这个时候虽然对象中没有el参数,但通过$mount(el)动态添加的方式,也能够使生命周期顺利进行。

template参数选项的有无对生命周期的影响

  • 1、如果Vue实例对象中有template参数选项,则将其作为模板编译成render函数
  • 2、如果没有template参数选项,则将外部的HTML作为模板编译(template),也就是说,template参数选项的优先级要比外部的HTML高
  • 3、如果1,2条件都不具备,则报错
<div id="vue_det">
    {{info}} 这是在outer HTML中的
</div>
<script>
    var vm = new Vue({
        el: '#vue_det',
        template: "<h1>{{info +'这是在template中的'}}</h1>",
        data: {
            info: "This Test"
        },
    })
</script>

执行上面的代码,输入页面显示为 This Test 这是在template中的

render选项参数比template更接近Vue解析器!所以综合排列如下:render函数选项 > template参数 > 外部HTML;Vue的编译实际上是指Vue把模板编译成 render 函数的过程

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

Vue.nextTick()官方解释:在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

什么时候需要用的Vue.nextTick()

在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中,因为在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。

所以解释起来就是:在某个动作有可能改变DOM元素结构的时候,对DOM一系列的js操作都要放进Vue.nextTick()的回调函数中。

相关文章

  • vue生命周期

    一 vue生命周期 Vue的生命周期:就是vue实例从创建到销毁的全过程 二 vue生命周期钩子 vue生命周期...

  • vue生命周期

    vue生命周期详: vue生命周期详解图: vue生命周期详解代码展示:

  • Vue生命周期

    Vue生命周期详解 一、Vue生命周期 与 作用 (生命周期钩子就是生命周期函数) (1)Vue生命周期:每个Vu...

  • 浅谈Vue的生命周期

    用Vue框架,熟悉它的生命周期可以让开发更好的进行。首先先看看官网的图,详细的给出了vue的生命周期: 它可以总共...

  • 浅谈vue的生命周期

    生命周期 在使用vue的过程中,对vue的生命周期的理解是最基础的开始,也许你不需要全部理解,但对其中最主要的几个...

  • vue3较vue2的特别之处 - 生命周期

    vue2 生命周期 vue3 生命周期 将 Vue2 的生命周期钩子代码更新到 Vue3 参考地址:https:/...

  • 前端之路-VUE面试题

    vue生命周期面试题vue 生命周期是什么? Vue 实例从创建到销毁的过程,就是生命周期 beforeCreat...

  • Vue.js入门(二):生命周期

    1 生命周期 Vue生命周期是Vue实例从创建到销毁的过程,就是生命周期。在Vue实例的生命周期过程中会运行生命周...

  • vue生命周期

    vue里的生命周期是什么? vue实例从创建到销毁的过程称之为vue的生命周期 vue的生命周期各阶段都做了什么?...

  • Vue 生命周期

    vue里的生命周期是什么? vue实例从创建到销毁的过程称之为vue的生命周期 vue的生命周期各阶段都做了什么?...

网友评论

      本文标题:浅谈vue的生命周期

      本文链接:https://www.haomeiwen.com/subject/hbcssqtx.html