详解Vue2.0生命周期

时间:2023-01-29 20:01:51

网上已经有很多关于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 之间

详解Vue2.0生命周期

在这个过程中,

  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 lang="en">
<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>

详解Vue2.0生命周期

用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);
}

详解Vue2.0生命周期

这里需要注意一点: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);
}

详解Vue2.0生命周期

这里我们可以清楚的看到进行了两次更新流程,但是对打印的结果有些疑问:第一次将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的值
},

详解Vue2.0生命周期

这里可以清楚看到两次数据改变时,数据和view层的更新状态。

beforeDestroy 和 destroyed

beforeDestroy:实例在销毁之前调用,此时实例仍然可用。

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

destroyed:vue实例销毁后调用。

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

详解Vue2.0生命周期的更多相关文章

  1. vue2&period;0 生命周期 简析

    Vue2.0 生命周期钩子函数: <template> <div id='app'> {{message}} </div> </template> va ...

  2. Spring第三天,详解Bean的生命周期,学会后让面试官无话可说!

    点击下方链接回顾往期 不要再说不会Spring了!Spring第一天,学会进大厂! Spring第二天,你必须知道容器注册组件的几种方式!学废它吊打面试官! 今天讲解Spring中Bean的生命周期. ...

  3. Vue2&period;0生命周期和钩子函数的一些理解

    转自:https://segmentfault.com/a/1190000008010666 前言 在使用vue一个多礼拜后,感觉现在还停留在初级阶段,虽然知道怎么和后端做数据交互,但是对于mount ...

  4. Vue2&period;0 —生命周期和钩子函数

    vue生命周期简介 咱们从上图可以很明显的看出现在vue2.0都包括了哪些生命周期的函数了. 生命周期探究 对于执行顺序和什么时候执行,看上面两个图基本有个了解了.下面我们将结合代码去看看钩子函数的执 ...

  5. 详解 Android Activity 生命周期

    从以下几个方面详细说一下Activity的生命周期: 1.回到主屏幕再打开和退出程序的时候. 2.屏幕旋转的时候. 3.打开其它的Activity的情况. 4.打开一个Layou透明的Activity ...

  6. 【Android基础】Fragment 详解之Fragment生命周期

    上一篇文章简单介绍了一下Fragment,这一篇文章会详细的说一下Fragment的生命周期和创建一个用户界面. Fragment的主要功能就是创建一个View,并且有一个生命周期来管理这个View的 ...

  7. 详解React的生命周期

    React生命周期 之前自己在学习React的时候,只是简单的理解了生命周期有这么一些,但是不知道大概的一个流程是怎么样的.那天在面试的时候,问到了.自己也有点懵,也没提前看,不过还是答上来了一些,这 ...

  8. 详解Android Activity生命周期

    转载注明来自:  http://www.cnblogs.com/wujiancheng/ 一.正常情况下Activity的生命周期:  Activity的生命周期大概可以归为三部分 整个的生命周期:o ...

  9. 【Spring Framework】Spring IOC详解及Bean生命周期详细过程

    Spring IOC 首先,在此之前,我们就必须先知道什么是ioc,ioc叫做控制反转,也可以称为依赖注入(DI),实际上依赖注入是ioc的另一种说法, 1.谁控制谁?: 在以前,对象的创建和销毁都是 ...

随机推荐

  1. android 学习随笔二十六(动画:属性动画)

    属性动画,属性动画是真正改变对象的某个属性的值 * 补间动画,只是一个动画效果,组件其实还在原来的位置上,xy没有改变1.位移:* 第一个参数target指定要显示动画的组件* 第二个参数proper ...

  2. iOS开发之&period;pch文件初识

    pch全称是“precompiled header”,即预编译头文件,自Xcode6诞生之日起,便在Supporting Files文件下消失多年.说起苹果对pch的爱恨情仇,其分析pch的作用便不言 ...

  3. Maven仓库详解

    转载自:Maven入门指南④:仓库   1 . 仓库简介 没有 Maven 时,项目用到的 .jar 文件通常需要拷贝到 /lib 目录,项目多了,拷贝的文件副本就多了,占用磁盘空间,且难于管理.Ma ...

  4. Linux下mpi环境配置与执行步骤(Ubuntu为例)

    转载注明出处: http://blog.csdn.net/bendanban/article/details/9136755 以两台计算机为例,将这两台计算机应用于MPI运行环境. 第一步:在两台机器 ...

  5. CentOS 7 的安装

    CentOS 7的安装 --------------------------- 安装前的准备: 1.去官网或是去网上下载好CentOS 7的镜像文件 下载主页: https://www.centos. ...

  6. U盘安装CentOS 7卡住在 mounting configuration file system

    使用UltraISO PE 9.6.0.3000刻录CentOS 7.2到U盘之后,在PC机上安装,一直卡住在此界面 网上各路大神各显神通,提供了各种各样的办法,后来根据一位网友的说法,顺利安装完成 ...

  7. 【2017-03-20】HTML框架,标题栏插入小图标,锚点,插入音频视频,滚动效果

    一.html框架   iframe 在网页中嵌入一个别的网页 1.格式: <iframe  src="链接地址" width="" height=&quo ...

  8. iOS ViewControllers 瘦身

    https://objccn.io/issue-1-1/ https://juejin.im/user/57ddfba4128fe10064cbb93a 把 Data Source 和其他 Proto ...

  9. yum卸载

    完全卸载依赖 -- 正常安装 yum install sl -- 列出操作 yum history list sl -- 根据显示install操作的id进行删除 yum history undo { ...

  10. &quot&semi;strace -p&quot&semi;非常有用,它减少了很多猜测工作,也不需要重新启动应用。lsof -p process&lowbar;id &plus;iostat &plus; sar -n DEV 1

    linux神器strace - youxin - 博客园https://www.cnblogs.com/youxin/p/8837771.html 某个进程突然占用了很多CPU? 或者某个进程看起来像 ...