【vue系列-05】vue的生命周期(详解)

简介: 【vue系列-05】vue的生命周期(详解)

一,vue的生命周期

在vue的官网中,vue的生命周期如下图所示,主要经历了如下几个阶段,分别是 beforeCreate,created,beforeMount,mounted,beforeUpdate,update,beforeDestroy,destroy ,主要由这八个阶段组成。


这边的vue实例和java中的spring中的bean对象一样,都有一套完成的加载流程,以及一套完整的生命周期,vue的生命周期的总览如下图,接下来通过下面这张图片对每个阶段做一个具体的分析。


0cdc4eae375b40e9bcacdc4c29f07187.png

1,创建流程

创建流程主要由两个阶段组成,一个是beforeCreate,另一个是created。这里的创建之前和创建之后指的是 数据监测和数据代理 的创建之前和创建之后,而不是vm,因为此时的vm还并没有创建出来。


470efa9727d545bf9cc75e840e1ddd4f.png

1.1,beforeCreate

在创建完这个Vue实例之后,首先会进入一个初始化阶段,此阶段初始化生命周期和事件,但是在此阶段,数据代理还并没有开始。在初始化阶段之后,就会经历vue的 beforeCreate 阶段,代码如下,其函数在vue实例中和这个data是平级的。

<div id="root">
    <h1>当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
</div>
new Vue({
    el:'#root',
    data:{n:1},
    methods:{add(){ this.n++ }},
    beforeCreate(){
        console.log('beforeCreate');
        console.log(this);
        debugger;
    }
})

其结果如下,由于数据代理并未初始化,因此这个阶段是拿不到vm对象以及_data数据的,因此在第一个 beforeCreate 阶段中,无法通过这个vm对象访到data中的数据和methods中方法。并且在下面的结果可以的得知是并没有 _data 的,并且也没有data数据中的 n 值,也没有add方法


d9bfc96378e74b039778253095f84409.png


1.2,created

在beforeCreate之后,还是处于一个初始化阶段,即init Injections & reactivity 阶段。该阶段就是初始化这个数据监测和数据代理的,这样就可以获取到代理对象,解析模板了。

<div id="root">
    <h1>当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
</div>
new Vue({
    el:'#root',
    data:{n:1},
    methods:{add(){ this.n++ }},
    ...
    created(){
        console.log('created');
        console.log(this);
        debugger;
    }
})

在初始化代理对象之后,就可以进入这个 created 阶段了。通过控制台的打印可以得知已经可以加载这个_data对象,由于初始化了这个数据监测,所以这个 get和set的两个方法也有了,由于初始化了这个数据代理,因此这个data中的n和method中的add都可以加载成功了,

80982e47e8af4279a593875819c02356.png



此时是可以通过vm对象获取到 data 中的属性和method 中的方法的。


2,挂载流程

在创建流程之后,还会有一个阶段来解析这个Vue模板,看下面的流程,就是开始解析模板,生成虚拟DOM到内存中,此时页面还不能显示好解析的内容,即还没有转成真实DOM。接下来就会进入两个挂载流程,一个是beforeMount,另一个是mounted。


f30ecf9f79144f9bad97a81bf807059a.png


接下来就是主要分析一下这两个挂载的流程以及所做的事情。

838cf3043bfe467c81dffe828c201f32.png



2.1,beforeMount

在挂载的函数上打一debugger,可以发现在执行到这这个 beforeMount 的时候,对应的页面是并没有进行解析的,因此可以初步确认这个挂载前的这个函数中的DOM元素是未经过Vue编译的,因此所有对Dom的操作都是不能奏效的。实际上这个DOM元素是Vue已经解析完成的真实DOM,但是此时的vue还没来的及将这些DOM向页面中存放。

<div id="root">
    <h1>当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
</div>
new Vue({
  el:'#root',
    data:{n:1},
    methods:{add(){ this.n++ }},
    ...
    beforeMount(){
        console.log('beforeMount');
        console.log(this);
        debugger;
    }
})

通过这个debugger的断点,此时的页面如下,可以发现页面上的值是原生的html,并不是经历过vue模板解析的值,因此可以得知上面还没有vue解析出来的DOM,同时也可以证明此时vue还没有来得及将编译的DOM存到页面中


493d1228d4944b91919df1a194f7210d.png


2.2,mounted

在经过这个 beforeMount 的阶段之后,Vue会将el中的数据存放在 $el 上,类似于做一个副本,此时会将内存中的虚拟DOM转化为真实DOM存在页面中。


在将真实的DOM插入页面之后,Vue就会开始调用这个 mounted 挂载的这个函数了。因为页面中已经呈现的是经过Vue编译的DOM了,因此在这个函数中对DOM的操作均有效,到此为止,初始化阶段正式结束。

<div id="root">
    <h1>当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
</div>
new Vue({
  el:'#root',
    data:{n:1},
    methods:{add(){ this.n++ }},
  ...
  mounted(){
        console.log('mounted');
        console.log(this);
        //操作DOM元素
        document.querySelector('h1').innerText = 'zhs'
    }
})

通过上面的代码以及下面的结果可知,在挂载阶段DOM元素已经是全部经过Vue解析的,因此展示在页面的值都是解析后的值,并且在这个阶段也可以有效的操作DOM元素。


ca90d47c3b1d47c08b0ffafdecf335ff.png


在这个挂载函数中,一般会进行这些操作:开启定时器,发送网络请求,订阅消息,绑定自定义事件等操作


3,更新流程

在挂载流程解释之后,接下来会进入更新流程,更新流程主要分为 beforeUpdate 和 updated 两个流程。


13b33c7b691c48c1ac3303073fab3880.png


3.1,beforeUpdate

就是说只要data中的数据发生改变,那么就会触发这个钩子函数,但是在这个阶段中,页面上渲染的数据和被改变的数据没有保持同步,就是页面还没有来得及展示被修改的值。

<div id="root">
    <h1 id='h1'>当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
</div>
new Vue({
  el:'#root',
    data:{n:1},
    methods:{add(){ this.n++ }},
  ...
  beforeUpdate(){
    //现在被修改的值
        console.log("vue实例数据是:" + this.n);
        debugger;
    }
})

通过下面的代码和下面的结果可知,vue实例中的数据和页面的数据是不一致的。


eced3bb3fea2464f952a2542cf30afda.png


3.2,updated

在这个beforeUpdate结束之后,会经过一个 Virtual DOM re-render and patch 阶段,在这个阶段,就会生成新的虚拟DOM,随后通过diff算法,实现新旧的虚拟DOM的比较,最终完成页面的更新。


此时这个数据是新的,页面也是最新的,并且数据和页面是保持一致的。

<div id="root">
    <h1 id='h1'>当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
</div>
new Vue({
  el:'#root',
    data:{n:1},
    methods:{add(){ this.n++ }},
  ...
  updated(){
    console.log(updated);
    //现在被修改的值
        console.log("vue实例数据是:" + this.n);
        debugger;
    }
})

通过上面的代码和下面的结果可知,数据和页面是同步的


844adeec19b340a885eb9b2e131de903.png


4,销毁流程

接下来就进入最后一个流程,销毁流程,销毁用官网的话来说:清理它与其他实例的链接,解绑他的全部指令以及时间监听器。主要是由两个部分组成,分别是 beforeDestry 和 destroyed


b9025ee1525e4d0f98e11a448ca76fe2.png


4.1,beforeDestry

销毁需要调用这个 this.$destroy() 方法来实现。在销毁 beforeDestry 的这个函数中,销毁的实例中的所有的data,methods还有指令等等都是处于可用状态,但是不能对实例中的具体的数据和方法进行一个操作。


设置标签

<div id="root">
    <button @click = "bey">点我销毁</button>
</div>
new Vue({
  el:'#root',
    data:{n:1},
    methods:{
      bey(){this.$destroy()}
    },
  ...
  beforeDestroy(){
    console.log('beforeDestry');
    }
})

4.2,destroyed

在到了这个最终的销毁方法之后,vue实例算是彻底的被销毁了,但是页面上的数据是还在的,但是不能操作上面的数据了。

...
destroyed(){
  console.log('destroyed');
}

总代码如下

<!-- 一个容器,可以用于接收vue实力传来的数据,然后展示 -->
<div id="root">
    <h1 id="h1">当前的值n为:{{n}}</h1>
    <button @click = "add">点我+1</button>
    <button @click = "bey">点我销毁</button>
</div>
<script type="text/javascript" >
    Vue.config.productionTip = false,   //阻止vue启动时提示生产提示
    new Vue({
        el:'#root',
        data:{n:1},
        methods:{
            add(){ this.n++ },
            bey(){this.$destroy()}
        },
        beforeCreate(){
            console.log('beforeCreate');
        },
        created(){
            console.log('created');
        },
        beforeMount(){
            console.log('beforeMount');
        },
        mounted(){
            console.log('mounted');
        },
        beforeUpdate(){
            console.log('beforeUpdate');
        },
        updated(){
            console.log('updated');
        },
        beforeDestroy(){
          console.log('beforeDestry');
            console.log("vue实例准备销毁了");
        },
        destroyed(){
            console.log('destry');
            console.log("vue实例已经销毁了");
        }
    })
</script>

二,vue的生命周期总结

常用的生命周期钩子:


1,mounted:发送ajax、启动定时器、绑定自定义事件、消息订阅等初始化操作


2,beforeDestroy:清除定时器、解绑自定义事件、取消消息订阅等


销毁vue实例之后


1,借助vue开发者工具是看不到任何消息的


2,销毁后自定义事件会失效,但是原生的DOM事件依然有效


3,一般不要在beforeDestory中操作数据,因为该钩子并不会触发更新流程

相关文章
|
3月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
460 0
|
3月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
3月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
326 17
|
3月前
|
监控 JavaScript 前端开发
Vue 文件批量下载组件封装完整使用方法及优化方案解析
本文详细介绍了批量下载功能的技术实现与组件封装方案。主要包括两种实现方式:**前端打包方案(基于file-saver和jszip)** 和 **后端打包方案**。前者通过前端直接将文件打包为ZIP下载,适合小文件场景;后者由后端生成ZIP文件流返回,适用于大文件或大量文件下载。同时,提供了可复用的Vue组件`BatchDownload`,支持进度条、失败提示等功能。此外,还扩展了下载进度监控和断点续传等高级功能,并针对跨域、性能优化及用户体验改进提出了建议。可根据实际需求选择合适方案并快速集成到项目中。
316 17
|
3月前
|
JavaScript 前端开发 UED
Vue 手风琴实现的三种常用方式及长尾关键词解析
手风琴效果是Vue开发中常见的交互组件,可节省页面空间、提升用户体验。本文介绍三种实现方式:1) 原生Vue结合数据绑定与CSS动画;2) 使用Element UI等组件库快速构建;3) 自定义指令操作DOM实现独特效果。每种方式适用于不同场景,可根据项目需求选择。示例包括产品特性页、后台菜单及FAQ展示,灵活满足多样需求。附代码示例与资源链接,助你高效实现手风琴功能。
140 10
|
3月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件的实现代码:支持自定义表情库、快捷键发送和输入框联动的聊天表情解决方案
本文详细介绍了在 Vue 项目中实现一个功能完善、交互友好的表情包输入组件的方法,并提供了具体的应用实例。组件设计包含表情分类展示、响应式布局、与输入框的交互及样式定制等功能。通过核心技术实现,如将表情插入输入框光标位置和点击外部关闭选择器,确保用户体验流畅。同时探讨了性能优化策略,如懒加载和虚拟滚动,以及扩展性方案,如自定义主题和国际化支持。最终,展示了如何在聊天界面中集成该组件,为用户提供丰富的表情输入体验。
258 8
|
3月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
165 1
|
3月前
|
JavaScript API 开发者
Vue框架中常见指令的应用概述。
通过以上的详细解析,你应该已经初窥Vue.js的指令的威力了。它们是Vue声明式编程模型的核心之一,无论是构建简单的静态网站还是复杂的单页面应用,你都会经常用到。记住,尽管Vue提供了大量预定义的指令,你还可以创建自定义指令以满足特定的需求。为你的Vue应用程序加上这些功能增强器,让编码变得更轻松、更愉快吧!
62 1
|
3月前
|
存储 JavaScript 前端开发
如何高效实现 vue 文件批量下载及相关操作技巧
在Vue项目中,实现文件批量下载是常见需求。例如文档管理系统或图片库应用中,用户可能需要一次性下载多个文件。本文介绍了三种技术方案:1) 使用`file-saver`和`jszip`插件在前端打包文件为ZIP并下载;2) 借助后端接口完成文件压缩与传输;3) 使用`StreamSaver`解决大文件下载问题。同时,通过在线教育平台的实例详细说明了前后端的具体实现步骤,帮助开发者根据项目需求选择合适方案。
223 0
|
3月前
|
JavaScript 前端开发 UED
Vue 项目中如何自定义实用的进度条组件
本文介绍了如何使用Vue.js创建一个灵活多样的自定义进度条组件。该组件可接受进度段数据数组作为输入,动态渲染进度段,支持动画效果和内容展示。当进度超出总长时,超出部分将以红色填充。文章详细描述了组件的设计目标、实现步骤(包括props定义、宽度计算、模板渲染、动画处理及超出部分的显示),并提供了使用示例。通过此组件,开发者可根据项目需求灵活展示进度情况,优化用户体验。资源地址:[https://pan.quark.cn/s/35324205c62b](https://pan.quark.cn/s/35324205c62b)。
105 0