深入学习Vue nextTick的用法及原理


Posted in Javascript onOctober 08, 2019

Vue.nextTick是Vue官方给我们提供的一个API(方法),作用是在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM;

那么我们的理解是:当数据发生变化之后,DOM视图并不会立即更新,如果我们在发生变化之后立马去获取某个节点或者某个节点的值,很有可能结果就是undefined;因为Vue实现响应式并不是数据发生变化之后DOM立即变化,而是按一定的策略进行DOM的更新;

来看一个小demo:

App.vue 

<template>
 <div id="app">
    <div ref="message">{{msg}}</div>
    <div v-if="msg1">{{msg1}}</div>
    <button @click="changeMsg">Change the Message</button>
 </div>
</template>

<script>
export default {
 name: 'App',
 data(){
  return {
   msg:"Hello Vue",
   msg1: '',
  }
 },
 methods:{
  changeMsg(){
   this.msg='hello world';
   this.msg1=this.$refs.message.innerHTML;
    console.log("更新DOM之前:"+this.msg1)
  }
 }
}
</script>

<style>
#app {
 font-family: 'Avenir', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

深入学习Vue nextTick的用法及原理

我们通过运行代码能够看到当我们不在this.$nextTick方法里面进行DOM操作的时候,this.$refs.message.innerHTML的值存储的还是之前的初始值;

修改代码:

App.vue

<template>
 <div id="app">
    <div ref="message">{{msg}}</div>
    <div v-if="msg1">{{msg1}}</div>
    <button @click="changeMsg">Change the Message</button>
 </div>
</template>

<script>
export default {
 name: 'App', 
 data(){
  return {
   msg:"Hello Vue",
   msg1: '',
  }
 },
 methods:{
  changeMsg(){
   this.msg='hello world';
   // this.msg1=this.$refs.message.innerHTML;
   // console.log("更新DOM之前:"+this.msg1)
    this.$nextTick(()=>{
     this.msg1=this.$refs.message.innerHTML;
     console.log("更新DOM之后:"+this.msg1)
    })
  }
 }
}
</script>

<style>
#app {
 font-family: 'Avenir', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

深入学习Vue nextTick的用法及原理

修改代码之后我们可以发现,使用this.$nextTick很容易的就接收到了更新后的值,正如官网解释:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM;

再来修改代码对比一下:

App.vue

<template>
 <div id="app">
    <div ref="message">{{msg}}</div>
    <div v-if="msg1">{{msg1}}</div>
    <button @click="changeMsg">Change the Message</button>
 </div>
</template>

<script>
export default {
 name: 'App', 
 data(){
  return {
   msg:"Hello Vue",
   msg1: '',
  }
 },
 methods:{
  changeMsg(){
   this.msg='hello world';
   this.msg1=this.$refs.message.innerHTML;
    console.log("更新DOM之前:"+this.msg1)
    this.$nextTick(()=>{
     this.msg1=this.$refs.message.innerHTML;
     console.log("更新DOM之后:"+this.msg1)
    })
  }
 }
}
</script>

<style>
#app {
 font-family: 'Avenir', Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
 margin-top: 60px;
}
</style>

深入学习Vue nextTick的用法及原理

经过修改代码,我们现在可以很容易看出来this.$nextTick(callback)的作用,callback是回调函数也就是我们要进行操作DOM的事情;

应用场景:

在vue的生命周期钩子函数created()中进行DOM操作的时候一定要把DOM操作放入到this.$nextTick()中;

因为在created钩子函数触发的时候,DOM是没有进行渲染的;DOM没有进行渲染,然后进行DOM操作无疑是徒劳的;

所以我们在created中进行DOM操作的时候,一定要将DOM操作放入到this.$nextTick()中;

与之相反的是mounted,因为当触发mounted的时候,DOM的挂载和渲染都已经完成了,所以在mounted中进行DOM操作是不会有任何问题的;

因为DOM更新是异步的,像v-if指令判断增删DOM元素,我们在方法中给变量赋值的时候,如果不使用this.$nextTick(),我们很有可能拿到的还是初始值,如果想拿到更新后的值,需要使用this.$nextTick()方法

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
jquery获取radio值实例
Oct 16 Javascript
js实现的Easy Tabs选项卡用法实例
Sep 06 Javascript
JS实现的自定义显示加载等待图片插件(loading.gif)
Jun 17 Javascript
点击页面任何位置隐藏div的实现方法
Sep 05 Javascript
通过JS获取Request.QueryString()参数的值实现方法
Sep 27 Javascript
Bootstrap基本组件学习笔记之按钮组(8)
Dec 07 Javascript
通过修改360抢票的刷新频率和突破8车次限制实现方法
Jan 04 Javascript
weex里Vuex state使用storage持久化详解
Sep 09 Javascript
使用D3.js+Vue实现一个简单的柱形图
Aug 05 Javascript
layui+jquery支持IE8的表格分页方法
Sep 28 jQuery
Vue 实现登录界面验证码功能
Jan 03 Javascript
Vue常用传值方式、父传子、子传父及非父子实例分析
Feb 24 Javascript
jQuery 筛选器简单操作示例
Oct 02 #jQuery
jQuery 查找元素操作实例小结
Oct 02 #jQuery
JavaScript 作用域实例分析
Oct 02 #Javascript
JavaScript Dom 绑定事件操作实例详解
Oct 02 #Javascript
JavaScript 面向对象基础简单示例
Oct 02 #Javascript
Nautil 中使用双向数据绑定的实现
Oct 02 #Javascript
详解element-ui级联菜单(城市三级联动菜单)和回显问题
Oct 02 #Javascript
You might like
如何在PHP中使用Oracle数据库(2)
2006/10/09 PHP
一个PHP日历程序
2006/12/06 PHP
一个简洁的PHP可逆加密函数(分享)
2013/06/06 PHP
利用php递归实现无限分类 格式化数组的详解
2013/06/08 PHP
解析将多维数组转换为支持curl提交的一维数组格式
2013/07/08 PHP
PHP+Mysql实现多关键字与多字段生成SQL语句的函数
2014/11/05 PHP
php实现在服务器上创建目录的方法
2015/03/16 PHP
TNC vs BOOM BO3 第一场2.13
2021/03/10 DOTA
对采用动态原型方式无法展示继承机制得思考
2009/12/04 Javascript
js 如何实现对数据库的增删改查
2012/11/23 Javascript
js中自定义方法实现停留几秒sleep
2014/07/11 Javascript
JavaScript中的getTime()方法使用详解
2015/06/10 Javascript
工作中常用的js、jquery自定义扩展函数代码片段汇总
2016/12/22 Javascript
vuejs响应用户事件(如点击事件)
2017/03/14 Javascript
Node.js 实现简单的接口服务器的实例代码
2017/05/23 Javascript
如何理解Vue的.sync修饰符的使用
2017/08/17 Javascript
详解在React中跨组件分发状态的三种方法
2018/08/09 Javascript
Js中使用正则表达式验证输入是否有特殊字符
2018/09/07 Javascript
Vue实现一个无限加载列表功能
2018/11/13 Javascript
解决Vue watch里调用方法的坑
2020/11/07 Javascript
[44:47]Ti4 循环赛第三日 iG vs NaVi
2014/07/12 DOTA
Python中获取网页状态码的两个方法
2014/11/03 Python
用Python编写简单的微博爬虫
2016/03/04 Python
Python实现选择排序
2017/06/04 Python
python3+PyQt5实现自定义窗口部件Counters
2018/04/20 Python
利用Python如何批量修改数据库执行Sql文件
2018/07/29 Python
Python判断变量名是否合法的方法示例
2019/01/28 Python
Python中的Cookie模块如何使用
2020/06/04 Python
Python实现PS滤镜中的USM锐化效果
2020/12/04 Python
Python 里最强的地图绘制神器
2021/03/01 Python
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
电影T恤、80年代T恤和80年代服装:TV Store Online
2020/01/05 全球购物
使用useBean标志初始化BEAN时如何接受初始化参数
2012/02/11 面试题
《木笛》教学反思
2014/03/01 职场文书
使用CSS实现小三角边框原理解析
2021/11/07 HTML / CSS
Python学习之包与模块详解
2022/03/19 Python