百分百源码网-让建站变得如此简单! 登录 注册 签到领金币!

主页 | 如何升级VIP | TAG标签

当前位置: 主页>网站教程>JS教程> 一文理解Vue2.0生命周期
分享文章到:

一文理解Vue2.0生命周期

发布时间:09/01 来源:未知 浏览: 关键词:

网上已经有许多关于vue生命周期的文章,我的这篇文章的由来,其实是我对官网上描写的一句话的思索与懂得:“el被新创立的vm.$el更换”,所以文章更多的内容大概是在对vue生命周期中“created -> beforeMount -> mounted” 历程的懂得。

beforeCreate --> created 之间

在这个阶段初始化事件,停止数据不雅测。

created

vue实例创立完后被调取,此时已经完成了数据不雅测(data observer),属性和办法的运算,watch/event 事件回调的配置。

可调取methods中的办法,拜访和修改data中的数据,并触发响应式转变使DOM渲染更新,触发watch中响应的办法,computed相关属性停止从新运算。

一样在created时,停止ajax恳求初始化实例数据。

此时,vm.$el不成见。

created --> beforeMount 之间

在这个历程中,

  a、第一推断实例中可否有el选项,有的话连续向下编译,没有的话会休止编译,直到vm.$mount(el)被调取时才连续(el是挂载的DOM节点);

  b、接下来推断实例中可否有template,有的话将其作为模板编译成rander函数;

  c、没有template的话就,就将 挂载DOM元素的html(即el所对应的DOM元素及其内部的元素)提取出来作为模板编译;

*注:el所对应的DOM元素不克不及为body/html元素,由于在后面vue实例挂载时,el所对应的DOM元素及其内部的元素会被模板渲染出来的新的DOM所更换。

  d、假如实例对象中有rander函数,就直接通过它停止渲染操纵。

优先级:rander函数 > template > 外部html

此时,rander函数已经预备好并首次被调取。

在这个历程中,$el被初始化为实例中el选项所对应的DOM元素,所以在beforeMount时,用vm.$el猎取到的是挂载DOM元素的html。

beforeMount

beforeMount被调取时,此时$el可见。

beforeMount --> mounted 之间

在这个历程中,el被新创立的vm.$el所更换,并完成实例的挂载。即实例中的el选项被模板渲染创立出来的DOM元素所更换,页面中的挂载点被渲染出的vue实例代码段所更换。

Mounted

此时实例已挂载到DOM上,可以通过DOM API猎取实例中DOM节点。在操纵台打印vm.$el,发明此前的挂载点及内容已被更换成新的DOM。

下面通过栗子看一下这两个历程。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>
</head>
<body>
<div id="app">
    <a id='ela' href="">{{message}}</a>
</div>
</body>
<script>
    var app = new Vue({
        el: '#app',
        data: function () {
            return {
                message: 'hello'
            };
        },
        template: '<p id="elp">{{message}}</p>',
        beforeMount: function () {
            console.group('beforeMount 挂载前状态===============》');
            let state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            let a = document.getElementById('ela');
            let p = document.getElementById('elp');
            console.log(this.$el);
            console.log(state);
            console.log(a);    // <a id='ela' href="">{{message}}</a>
            console.log(p);     // null
        },
        mounted: function () {
            console.group('mounted 挂载完毕状态===============》');
            let state = {
                'el': this.$el,
                'data': this.$data,
                'message': this.message
            }
            let a = document.getElementById('ela');
            let p = document.getElementById('elp');
            console.log(this.$el);
            console.log(state);
            console.log(a);    // null
            console.log(p);     // <p id="elp">father</p>
        }
</script>
</html>

用template/rander选项可以在操纵台分明的看到:挂载完成后,el被新创立的vm.$el更换。

挂载前是以初始的el和虚拟DOM的情势存在的,此时以template中的内容为模板,模板内容不成见,打印p标签为null;

挂载后,模板渲染的新DOM更换本来的el,原el所对应的DOM不存在,打印a标签为null。

beforeUpdate 和 updated

当data对象中数据更新时,会触发 beforeUpdate钩子,此时view层还没有更新。 beforeUpdate有下面几个需要留意的地方:

  a、更新的数据必需在模板中直接或间接的使用,才会触发beforeUpdate;

  b、在挂载此前,data中数据更新不会触发 beforeUpdate!即在created、beforeMount时改动数据不会触发更新流程;

  c、假如在beforeUpdate中,再次修改了该数据的值,会再次触发beforeUpdate钩子,停止两次更新流程。

updated时,view层已更新完毕。

(在上面的代码中增添两个钩子)

mounted: function () {
    this.message = 'first';
//     this.show = false;        // 由于模板中没有用到show,所以show的改动不会触发beforeUpdate
},
beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
},
updated: function () {
    console.group('updated 更新完成状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
}

这里需要留意一点:view层我们需要通过innerHTML猎取对应元素节点中的内容,而不克不及直接猎取元素节点。直接猎取元素节点,在操纵台打印出来的view层中的数据都是更新之后的状态,不克不及打印出实时的准确的值,这应当和Chrome操纵台的输出有关。

针对第三条,我们看一下下面的代码演示:

mounted: function () {
    this.message = 'first';
},
beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
    this.message = 'second';    // 此时在beforeUpdate中再次修改了message的值
},
updated: function () {
    console.group('updated 更新完成状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
}

这里我们可以分明的看到停止了两次更新流程,但是对打印的结果有些疑问:第一次将message的值改为first,并且以first来渲染更新DOM,那么第一次调取updated时,message和DOM中的值都应当是first,而此时打印出来的时second。我懂得的是,在第一次施行updated时,DOM就已经完成了第二次渲染更新,详细的历程还需要通过之后对源码的学习去懂得。这里各位有不一样的懂得或者更具体的说明,可以在评论区留言,共同学习。

在这里,我们可以在beforeUpdate中加按时器去修改message的值,就可以等候第一次数据改动,DOM更新渲染完成后,停止第二次数据改动。

beforeUpdate: function () {
    console.group('beforeUpdate 更新前状态===============》');
    let elp = document.getElementById('elp').innerHTML;
    console.log('message:' + this.message);
    console.log('DOM:' + elp);
    var that = this;
    setTimeout(function(){
      that.message = 'second';
    });
//    this.message = 'second';    // 此时在beforeUpdate中再次修改了message的值
},

这里可以分明看到两次数据改动时,数据和view层的更新状态。

beforeDestroy 和 destroyed

beforeDestroy:实例在烧毁此前调取,此时实例依然可用。

beforeDestroy -> destroyed: Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被烧毁。

destroyed:vue实例烧毁后调取。

结尾:关于vue生命周期就总结完毕,有错误的地方烦请指出,会及时修改!

以上就是一文理解Vue2.0生命周期的具体内容,更多请关注百分百源码网其它相关文章!

打赏

打赏

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

百分百源码网 建议打赏1~10元,土豪随意,感谢您的阅读!

共有150人阅读,期待你的评论!发表评论
昵称: 网址: 验证码: 点击我更换图片
最新评论

本文标签

广告赞助

能出一分力是一分吧!

订阅获得更多模板

本文标签

广告赞助

订阅获得更多模板