Vue中this.$nextTick()的具体使用
作者:Litt_White 发布时间:2023-07-02 16:59:30
1、官网说法
在下次
DOM 更新
循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM
。
核心点有2个:DOM 更新
和获取更新后的 DOM
。
DOM 更新
,可以理解为:Vue 的DOM更新机制,那 Vue 的DOM更新机制是什么?
2、DOM 更新
首先,我们要知道:Vue实现响应式并不是数据发生变化之后DOM立即变化
,而是异步执行DOM更新
的。
通过代码我们验证下:不是数据发生变化之后DOM立即变化
<template>
<div class="test">
<div>
<button @click="test" ref="btn">{{ msg }}</button>
</div>
</div>
</template>
<script>
export default {
data () {
return {
msg: '按钮'
}
},
methods: {
test () {
this.msg = '信息改变了。。。。'
console.log('打印结果:' + this.$refs.btn.innerText) // 打印结果:按钮
}
}
}
</script>
此时log结果是:
打印结果:‘按钮‘
。而不是后来的‘信息改变了。。。。’
,
原因:Vue的响应式是异步执行DOM更新
。
异步执行DOM更新
Vue 在更新 DOM 时是异步执行的。只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更。如果同一个 watcher 被多次触发,只会被推入到队列中一次。这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的。然后,在下一个的事件循环 “tick" 中,Vue 刷新队列并执行实际(已去重的)工作。
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步。
主线程不断执行任务
、获取任务
、执行任务
……的过程叫做事件循环
简单的理解:
vue在修改数据后,视图不会立刻更新,而是等同一事件循环中的所有数据变化完成
以后,再进行视图更新.
为什么不同步进行DOM更新呢?
因为如果同步进行DOM更新,则每次对响应式数据进行修改就都会触发setter -> 通知watcher -> 触发re-render -> 生成new vnode(vdom) -> patch(更新真实DOM)
。如果每次修改数据都会走一遍这个流程是非常消耗性能的,所以使用异步更新 DOM
的策略,先对数据修改进行整合
,再使用最终的整合结果一次性对 DOM 进行更新
。
3、获取更新后的 DOM
<template>
<div class="test">
<div>
<button @click="test" ref="btn">{{ msg1 }}</button>
</div>
<div>
<button @click="test2" ref="btn">{{ msg2 }}</button>
</div>
</div>
</template>
<script>
export default {
data () {
return {
msg1: '按钮1',
msg2: '按钮2'
}
},
methods: {
test () {
this.msg1 = '信息改变了。。。。'
console.log('打印结果:' + this.$refs.btn.innerText) // 打印结果:按钮
},
test2 () {
this.msg2 = '使用this.$nextTick后'
this.$nextTick(function () {
console.log('打印结果:' + this.$refs.btn.innerText) // 打印结果:使用this.$nextTick后
})
}
}
}
</script>
通过使用
this.$nextTick
,此时的打印结果就可以获取到打印结果:使用this.$nextTick后
的信息。
4、小结:this.$nextTick()的使用场景
在Vue生命周期的
created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中
。原因是在created()钩子函数执行的时候DOM 其实并未进行任何渲染,而此时进行DOM操作无异于徒劳,所以此处一定要将DOM操作的js代码放进Vue.nextTick()的回调函数中。与之对应的就是mounted钩子函数,因为该钩子函数执行时所有的DOM挂载和渲染都已完成,此时在该钩子函数中进行任何DOM操作都不会有问题 。在数据变化后要执行的某个操作,当你设置 this.msg1 = ‘信息改变了。。。。’ ,DOM并不会马上更新,而是在异步队列被清除,也就是下一个事件循环开始时执行更新时才会进行必要的DOM更新。如果此时你想要根据更新的 DOM 状态去做某些事情,就会出现问题。。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在
数据变化之后立即使用 Vue.nextTick(callback)
。这样回调函数在 DOM 更新完成后就会调用
。
来源:https://blog.csdn.net/Litt_White/article/details/128885148


猜你喜欢
- 数据加密是一种保护数据安全的技术,通过对数据进行编码,使得未经授权的用户无法读取或改动数据。加密是通过使用加密算法和密钥实现的。加密算法是一
- 这篇文章主要介绍了python通过移动端访问查看电脑界面,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的
- 抛出问题:求一数组如 l = [0, 1, 2, 3, -4, 5, -6],求该数组的最大连续子数组的和 如结果为[0,1,2,3,-4,
- 前言TensorFlow目前在移动端是无法training的,只能跑已经训练好的模型,但一般的保存方式只有单一保存参数或者graph的,如何
- 1005:创建表失败1006:创建数据库失败1007:数据库已存在,创建数据库失败1008:数据库不存在,删除数据库失败1009:不能删除数
- 现在,ORM框架、Web框架和配置都已就绪,我们可以开始编写一个最简单的MVC,把它们全部启动起来。通过Web框架的@decorator和O
- 相关知识点:#key-value#字典是无序的,因为他没有下标,通过key找info={ 'stu01':"liu
- 单线程实现多个定时器NewTimer.py#!/usr/bin/env pythonfrom heapq import *from thre
- 关于Python的格式化字符串,几乎所有接触过Python语言的人都知道其中一种,即使用运算符%,但对于绝大多数初学者来说也仅此而已。因此,
- 蒙特卡罗方法是一种统计模拟方法,由冯·诺依曼和乌拉姆提出,在大量的随机数下,根据概率估计结果,随机数据越多,获得的结果越精确。下面我们将用p
- 首先还是应该科普下函数参数传递机制,传值和传引用是什么意思?函数参数传递机制问题在本质上是调用函数(过程)和被调用函数(过程)在调用发生时进
- mysql允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,
- MySQL中concat函数 使用方法:CONCAT(str1,str2,…)返回结果为连接参数产生的字符串。如有任何一个参数为NULL ,
- 一、局部变量1 定义在{}里面的变量时局部变量,只能在{}里面有效2 执行到定义的那句话,开始分配内存空间,离开作用域自动进行释放3 作用域
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:jquery读取xml文件 <!DOCTYPE html PUBLIC "
- 简单的 TodoList实现一个简单的 todolist,当我输入内容后,点击提交自动添加在下面,如下图所示:用代码实现这个效果:<d
- 可以压缩文件和目录。package mainimport ( "archive/zip" &qu
- 之前做课设的时候舍友遇到了需要生成500w量级车牌号的问题,于是我便写了一个随机生成车牌号的程序,希望各位采纳。注:Python实现impo
- 没有使用队列,也没有线程池还在学习只是多线程 #coding:utf8 import urllib2,sys,re import threa
- Asp中Server.ScriptTimeOut属性需要注意的一点Server.ScriptTimeout?这个属性给定Asp脚本执行的最大