Vue中生命周期的理解

23次阅读

共计 4218 个字符,预计需要花费 11 分钟才能阅读完成。

代码及结果截图

HTML

<div id="app">
    <p>{{message}}</p>
    <h1>{{message + '这是在 outer HTML 中的'}}</h1>
</div>

js

 var app = new Vue({
    el: '#app',
    data: {message : "xuxiao is boy"},
    template:"<h1>{{message +' 这是在 template 中的 '}}</h1>",
    // render: function(createElement) {//     return createElement('h1', 'this is createElement')
    // },
    beforeCreate: function () {console.group('beforeCreate 创建前状态 ===============》');
        console.log("%c%s", "color:red" , "el     :" + this.$el); //undefined
        console.log("%c%s", "color:red","data   :" + this.$data); //undefined
        console.log("%c%s", "color:red","message:" + this.message)
    },
    created: function () {console.group('created 创建完毕状态 ===============》');
        console.log("%c%s", "color:red","el     :" + this.$el); //undefined
        console.log("%c%s", "color:red","data   :" + this.$data); // 已被初始化
        console.log("%c%s", "color:red","message:" + this.message); // 已被初始化
    },
    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   :" + this.$data); // 已被初始化
        console.log("%c%s", "color:red","message:" + this.message); // 已被初始化
    },
    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   :" + this.$data); // 已被初始化
        console.log("%c%s", "color:red","message:" + this.message); // 已被初始化
    },
    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   :" + this.$data);
        console.log("%c%s", "color:red","message:" + this.message);
    },
    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   :" + this.$data);
        console.log("%c%s", "color:red","message:" + this.message);
    },
    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   :" + this.$data);
        console.log("%c%s", "color:red","message:" + this.message);
    },
    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   :" + this.$data);
        console.log("%c%s", "color:red","message:" + this.message)
    }
})

最终结果



初始化阶段

beforecreate

在这个阶段,完成实例初始化,初始化非响应式变量 this 指向创建的实例;可以在这加个 loading 事件;data computed watch methods 上的方法和数据均不能访问,这个时候的 Vue 实例还什么都没有,但是在这个阶段 $route 对象是存在的,可以根据路由信息进行重定向之类的操作;这个阶段的 data 对象未完成初始化,el 也没有完成初始化;DOM 还没有开始

created【创建完成】

在模板渲染成 HTML 前调用,即通常初始化一些属性值,然后再渲染成视图,未挂载 DOM;created 时还没完成挂载,无法通过 id 等获得 DOM 元素

实例创建完成 完成数据 (data props computed) 的初始化 导入依赖项。可访问 data computed watch methods 上的方法和数据;不能访问 el【初始化还未完成】,ref 为空数组;不能对元素进行操作;可在这结束 loading,还做一些初始化,实现函数自执行,

可以对 data 数据进行操作,可进行一些请求,请求不易过多,避免白屏时间太长。el 还是 undefined,

而数据已经与 data 中的属性进行绑定(放在 data 中属性当值发生改变的同时,视图也会发生变化),


在这里可以在渲染前倒数第二次更改数据的机会,不会触发其他的钩子函数,** 一般可以在这里做初始数据的获取 **

** 若在此阶段进行的 DOM 操作一定要放在 Vue.nextTick() 的回调函数中;因为 created() 钩子函数执行的时候 DOM 其实并未进行任何渲染 **

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

模板编译阶段

beforemount & mount

在 created 后,beforemount 前,会检查 el 选项,没有就会调用 vm.$mount(),然后就会继续检查 template,没有的话就绑定 el 选项的 html,进入 beforemount 后,编译模板为虚拟的 DOM,,开始 render,将虚拟 DOM 渲染到页面上;

从 created 到 beforeMount 的过程中,

     var app = new Vue({
            el: '#app',
            data: {message : "xuxiao is boy"},
            template:"<h1>{{message +' 这是在 template 中的 '}}</h1>",
            // render: function(createElement) {//     return createElement('h1', 'this is createElement')
            // },

首先会判断 vue 实例中有没有 el 选项,如果有的话则进行下面的编译,但是如果没有 el 选项,则停止生命周期,直到 vue 实例上调用 vm.$mount(el)。

如果有 el,再判断是否有 template 参数,如果有,则把其当作模板编译成 render 函数,

如果没有,则把外部的 html 作为模板编译。template 中的模板优先级高于 outer HTML 模板。


这是把 outerHTML 当作模板编译了

<div id=”app”>

<p>{{message}}</p>
<h1>{{message + '这是在 outer HTML 中的'}}</h1>

</div>

如果把实例中 render function 选项的注释去掉,则直接用 render function 里的,得到网页如下

所以按优先级来说 render function>template>outerHTML
————————————————

在 vue 对象中还有一个 render 函数,它是以 createElement 作为参数,然后做渲染操作,而且我们可以直接嵌入 JSX.
综合排名优先级:render 函数选项 > template 选项 > outer HTML.

挂载阶段

beforeMount【挂载之前】

载入前(完成了 data 和 el 数据初始化),

但是 页面中的内容还是 vue 中的占位符

$el 属性已存在,是虚拟 dom,只是数据未挂载到模板中。

data 中的 message 信息没有被挂在到 Bom 节点中,

在这里可以在 渲染前最后一次更改数据的机会,不会触发其他的钩子函数,一般可以在这里做初始数据的获取

mounted【成功挂载】

完成创建 vm,

完成 el 的双向绑定,完成挂载 dom 和渲染,可以在这个阶段对挂载的 DOM 进行操作;

ref 可在这发起后端请求,拿回数据,配合路由钩子做一些事情;可对 DOM 进行操作

载入后 html 已经渲染(ajax 请求可以放在这个函数中),把 vue 实例中的 data 里的 message 挂载到 BOM 节点中去

正文完
 0