vue生命周期(lifecycle)以及对nextTick的理解

  每个Vue实例在被创建的时候,都会经历一系列初始化的过程。比如说需要设置数据监听、模板编译、将实例挂载到DOM结构上并且在数据变化时对DOM结构进行更新等等。Vue允许开发者在不同的生命周期运行一些钩子函数(hook),给开发者在不同的生命周期中添加自己代码的机会。所有的生命周期钩子自动绑定 this 上下文到实例中,因此你可以访问数据,对属性和方法进行运算,这也意味着我们不能够用箭头函数来定义生命周期函数。ok,生命周期的定义就到这里,下面看一下vue具体有哪些生命周期,以及再不同的生命周期里面会发生什么事情。

  官方给的生命周期钩子函数如下:

  #beforeCreate

  #created

  #beforeMount

  #mounted

  #beforeUpdate

  #updated

  #beforeDestroy

  #destroyed

  #errorCaptured

  #activated

  #deactivated

  在这里钩子函数里面,着重看前八个,后面三个在实际开发中基本涉及不到,如果有兴趣了解可移步到官方文档https://cn.vuejs.org/v2/api/#%E9%80%89%E9%A1%B9-%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90

 1 var vm = {
 2     el: ‘#app‘,
 3     data: {
 4         message: ‘hello world.‘
 5     },
 6     beforeCreate: function() {
 7         // 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
 8         // 在这个生命周期里,vue实例还只是空壳,数据和dom结构都还没有加载
 9         console.log(this.message);  // undefined
10     },
11     created: function() {
12         // 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer),属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始,$el 目前不可见。
13         // 在这个生命周期里,数据已经加载完成,并且在这里面修改数据并不会出发update函数。
14         // 一般情况下会在这里面做一些异步数据的获取,比如说从服务器获取数据到本地。
15         console.log(this.message);  // ‘hello world‘
16     },
17     beforeMount: function() {
18         // 在挂载开始之前被调用:相关的 render 函数首次被调用。
19         // 在这里面,虚拟DOM已经加载完毕,但是对应的真实DOM还未加载,在这里面是获取不到真实DOM结点的。
20         // 接下来执行render,加载真实DOM。
21         // 在这里面进行数据修改依旧不会触发update函数。
22     },
23     mounted: function() {
24         // 在这里面,真实DOM、数据、事件处理已经加载完毕,可以进行对应的修改。
25         // 从这里开始进行数据修改都会触发update函数。
26     },
27     beforeUpdate: function() {
28         // 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。
29         // 这个没啥好说的,在数据修改(或者说要重新进行渲染)的时候会触发的钩子函数。
30         // 值得注意的是,千万不要在这里面进行数据修改,否则会陷入死循环!道理你自己思考一下就知道为什么了!
31
32     },
33     updated: function() {
34         // 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
35         // 当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。然而在大多数情况下,你应该避免在此期间更改状态。如果要相应状态改变,通常最好使用计算属性或 watcher 取而代之。
36         // 同样的,在数据修改完毕之后会调用的钩子函数。
37         // 在这里面一样不能进行数据修改!!!谨记!!!
38
39     },
40     beforeDestroy: function() {
41         // 实例销毁之前调用。在这一步,实例仍然完全可用。
42         // 销毁前执行(手动使用$destroy方法被调用的时候就会执行),一般在这里善后:清除计时器、清除非指令绑定的事件等等。
43     },
44     destroyed: function() {
45         // Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。
46         // 组件的数据绑定、监听...都去掉了,只剩下dom空壳,这里也可以善后。
47     }
48 }

  上面我们说到,在发生数据修改的时候都会触发beforeUpdate和updated这两个钩子函数,但是如果要对特定的修改执行update函数就会变得很麻烦。官方为此提供了另外一种解决办法,那就是$nextTick。$nextTick()是在下次 DOM 更新循环结束之后执行延迟回调,可以在修改数据之后立即使用这个方法,获取更新后的 DOM。简单的理解是:当数据更新了,在dom中渲染后,自动执行该函数。下面举个简单的例子:

 1 <template>
 2   <div>
 3     <span ref="span">{{ message }}</span>
 4   </div>
 5 </template>
 6
 7 <script>
 8 export default {
 9   name: ‘test‘,
10   data () {
11     return {
12       message: "初始值"
13     }
14   },
15   methods:{
16     changeMsg: function(){
17       this.message =  "修改后的值";
18       console.log(this.$refs.span.innerText);   //原始值
19     }
20   },
21   created() {
22       this.changeMsg();
23   }
24 }
25 </script>

  这是因为在修改完message之后,尚未执行update函数,对应的DOM结构还未发生改变。使用nextTick稍作修改:

 1 <template>
 2   <div>
 3     <span ref="span">{{ message }}</span>
 4   </div>
 5 </template>
 6
 7 <script>
 8 export default {
 9   name: ‘test‘,
10   data () {
11     return {
12       message: "初始值"
13     }
14   },
15   methods:{
16     changeMsg: function(){
17       this.message =  "修改后的值";
18       this.$nextTick(function(){
19         console.log(that.$refs.span.innerText);  //修改后的值
20       });
21
22     }
23   },
24   created() {
25       this.changeMsg();
26   }
27 }
28 </script>
29  

  因此,在某些有特殊需求的情况下,是可以使用nextTick来代替update进行使用的。那么什么情况下需要使用到nextTick()呢?

  一、需要在created()钩子函数进行的DOM操作。因为在created()钩子函数执行时,真实DOM 并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进nextTick()的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM挂载已完成。

  二、需要在改变DOM之后基于新的DOM做点什么,对新DOM一系列的js操作都需要放进nextTick()的回调函数中。

Vue.nextTick(callback)的原理:

  Vue是异步执行dom更新的,一旦观察到数据变化,Vue就会开启一个队列,然后把在同一个事件循环 (event loop) 当中观察到数据变化的 watcher 推送进这个队列。如果这个watcher被触发多次,只会被推送到队列一次。这种缓冲行为可以有效的去掉重复数据造成的不必要的计算和DOM操作。而在下一个事件循环时,Vue会清空队列,并进行必要的DOM更新。
  当你设置 vm.data = ‘new value‘,DOM 并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用 Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。

原文地址:https://www.cnblogs.com/hmchen/p/12676736.html

时间: 2024-12-11 10:54:27

vue生命周期(lifecycle)以及对nextTick的理解的相关文章

Vue 生命周期LIFECYCLE是8个吗?

vue生命周期钩子个数是:11个. export const LIFECYCLE_HOOKS = [ 'beforeCreate', 'created', 'beforeMount', 'mounted', 'beforeUpdate', 'updated', 'beforeDestroy', 'destroyed', 'activated', 'deactivated', 'errorCaptured' ] github地址: https://github.com/vuejs/vue/blob

简单记录一下vue生命周期及 父组件和子组件生命周期钩子执行顺序

首先,vue生命周期可以用下图来简单理解 当然这也是官方文档的图片,详细的vue周期详解请参考这里 然而当同时存在父子组件的时候生命周期钩子是如何执行的呢? 请看下文: 加载渲染过程父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted 子组件更新过程父beforeUpdate->子beforeUpdate->子up

vue 生命周期初探

vue 以后发之势加上其独有的特性(压缩后很小),轻量级的MVVM框架,目前github star已有5.94万,而react 7万.由此可见是两个非常热门前端框架.这里就vue的生命周期做个初步体验. 发现看视频,动手之后,过段时间还是会忘,所以写一篇短文以备不时之需. 先附上官网的图片:vue生命周期 生命周期的钩子函数如果使用得当,会大大增加开发效率: 生命周期实践: 为了更好的查看beforeUpdate.updated,beforeDestroy,destroy钩子函数,使用v-on绑

Vue生命周期及业务场景使用

vue里的生命周期是什么? vue实例从创建到销毁的过程称之为vue的生命周期 vue的生命周期各阶段都做了什么? beforeCreate 实例创建前:这个阶段实例的data.methods是读不到的created 实例创建后:这个阶段已经完成了数据观测(data observer),属性和方法的运算, watch/event 事件回调.mount挂载阶段还没开始,$el 属性目前不可见,数据并没有在DOM元素上进行渲染beforeMount:在挂载开始之前被调用:相关的 render 函数首

vue生命周期钩子函数

转载自:https://segmentfault.com/a/1190000008879966 vue生命周期探究(一) 前言 在使用vue开发的过程中,我们经常会接触到生命周期的问题.那么你知道,一个标准的工程项目中,会有多少个生命周期勾子吗?让我们来一起来盘点一下: 根组件实例:8个 (beforeCreate.created.beforeMount.mounted.beforeUpdate.updated.beforeDestroy.destroyed) 组件实例:8个 (beforeCr

Vue生命周期详解(1)- 单个组件

刚接触vue,使用vue并没意识到生命周期的重要性.直到项目深入,在解决父组件异步加载数据传给子组件并渲染时首次渲染异常的问题时,浪费了很多时间,才发现自己对vue生命周期理解的欠缺.因此,这次专门重新学习一下vue的生命周期并总结在这里分享,希望对大家有所帮助. 首先上官方大图(是不是很高大上?然而,有点晦涩,对初学者不是很友好!) 不过不用担心,咱们程序员不就是实践出真知嘛!上代码: 1 <!DOCTYPE html> 2 <html lang="en">

vue生命周期的介绍

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>vue生命周期</title> 6 <script src="../js/vue.js"></script> 7 <meta name="viewport" content="width=devic

vue 生命周期

一 vue的生命周期如下图所示(很清晰) 二 vue生命周期的栗子 注意触发vue的created事件以后,this便指向vue实例,这点很重要 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue生命周期</title> <script src="../js/vue.js"></script> &

vue生命周期学习心得(下)

此文接vue生命周期学习心得(上)http://www.cnblogs.com/pengshadouble/p/7488330.html通过vue生命周期学习心得(上),大至了解了vue生命周期的8个阶段及相关钩子函数触发的时间点,这章我们通过简单的代码看一下具体的运行结果: <template> <div id="container"> <headers></headers> <router-view></router

Tomcat 8(九)解读Tomcat组件的生命周期(Lifecycle)

Tomcat 8(七)解读Bootstrap介绍过.运行startup.bat.将引发Tomcat一连串组件的启动.事实上这一连串启动是通过组件的生命周期(Lifecycle)实现的 今天来看看Lifecycle设计.解读Lifecycle.涉及到例如以下几个类 Lifecycle.LifecycleState.LifecycleEvent.LifecycleListener(位于org.apache.catalina) LifecycleBase.LifecycleSupport.Lifecy