0

0

一文了解Vue2.0生命周期

青灯夜游

青灯夜游

发布时间:2020-07-09 14:52:19

|

2271人浏览过

|

来源于博客园

转载

一文了解Vue2.0生命周期

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

CreateWise AI
CreateWise AI

为播客创作者设计的AI创作工具,AI自动去口癖、提交亮点和生成Show notes、标题等

下载

用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生命周期就总结完毕,有错误的地方烦请指出,会及时修改!

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
ajax教程
ajax教程

php中文网为大家带来ajax教程合集,Ajax是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,Ajax可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。php中文网还为大家带来ajax的相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

166

2023.06.14

ajax中文乱码解决方法
ajax中文乱码解决方法

ajax中文乱码解决方法有设置请求头部的字符编码、在服务器端设置响应头部的字符编码和使用encodeURIComponent对中文进行编码。本专题为大家提供ajax中文乱码相关的文章、下载、课程内容,供大家免费下载体验。

170

2023.08.31

ajax传递中文乱码怎么办
ajax传递中文乱码怎么办

ajax传递中文乱码的解决办法:1、设置统一的编码方式;2、服务器端编码;3、客户端解码;4、设置HTTP响应头;5、使用JSON格式。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

124

2023.11.15

ajax网站有哪些
ajax网站有哪些

使用ajax的网站有谷歌、维基百科、脸书、纽约时报、亚马逊、stackoverflow、twitter、hacker news、shopify和basecamp等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

260

2024.09.24

chrome什么意思
chrome什么意思

chrome是浏览器的意思,由Google开发的网络浏览器,它在2008年首次发布,并迅速成为全球最受欢迎的浏览器之一。本专题为大家提供chrome相关的文章、下载、课程内容,供大家免费下载体验。

1065

2023.08.11

chrome无法加载插件怎么办
chrome无法加载插件怎么办

chrome无法加载插件可以通过检查插件是否已正确安装、禁用和启用插件、清除插件缓存、更新浏览器和插件、检查网络连接和尝试在隐身模式下加载插件方法解决。更多关于chrome相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

845

2023.11.06

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

TypeScript类型系统进阶与大型前端项目实践
TypeScript类型系统进阶与大型前端项目实践

本专题围绕 TypeScript 在大型前端项目中的应用展开,深入讲解类型系统设计与工程化开发方法。内容包括泛型与高级类型、类型推断机制、声明文件编写、模块化结构设计以及代码规范管理。通过真实项目案例分析,帮助开发者构建类型安全、结构清晰、易维护的前端工程体系,提高团队协作效率与代码质量。

26

2026.03.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号