深入学习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 相关文章推荐
JavaScript使用技巧精萃[代码非常实用]
Nov 21 Javascript
jquery插件之easing 动态菜单
Aug 21 Javascript
Javascript继承机制的设计思想分享
Aug 28 Javascript
JS回调函数的应用简单实例
Sep 17 Javascript
详细解读JavaScript的跨浏览器事件处理
Aug 12 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
May 25 Javascript
JS实现的跨浏览器解析XML文件实例
Jun 21 Javascript
AngularJS 中的Promise --- $q服务详解
Sep 14 Javascript
通过Ajax使用FormData对象无刷新上传文件方法
Dec 08 Javascript
socket.io学习教程之基本应用(二)
Apr 29 Javascript
JQuery EasyUI的一些常用组件
Jul 12 jQuery
如何进行微信公众号开发的本地调试的方法
Jun 16 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中OR与|| AND与&amp;&amp;的区别总结
2013/10/26 PHP
codeigniter框架批量插入数据
2014/01/09 PHP
PHP调试函数和日志记录函数分享
2015/01/31 PHP
php计算给定日期所在周的开始日期和结束日期示例
2017/02/06 PHP
PHP设计模式之适配器模式定义与用法详解
2018/04/03 PHP
Jquery Ajax解析XML数据(同步及异步调用)简单实例
2014/02/12 Javascript
js实现按钮控制图片360度翻转特效的方法
2015/02/17 Javascript
JavaScript实现级联菜单的方法
2015/06/29 Javascript
解决JS请求服务器gbk文件乱码的问题
2015/10/16 Javascript
原生JavaScript制作微博发布面板效果
2016/03/11 Javascript
JavaScript知识点总结(十一)之js中的Object类详解
2016/05/31 Javascript
利用jQuery实现一个简单的表格上下翻页效果
2017/03/14 Javascript
JS实现简单短信验证码界面
2017/08/07 Javascript
node.js-v6新版安装具体步骤(分享)
2017/09/06 Javascript
Vue-cli创建项目从单页面到多页面的方法
2017/09/20 Javascript
微信小程序使用video组件播放视频功能示例【附源码下载】
2017/12/08 Javascript
JavaScript实现微信红包算法及问题解决方法
2018/04/26 Javascript
vue-router源码之history类的浅析
2019/05/21 Javascript
[43:57]LGD vs Mineski 2018国际邀请赛小组赛BO2 第二场 8.19
2018/08/21 DOTA
跟老齐学Python之集成开发环境(IDE)
2014/09/12 Python
Python实现Mysql数据库连接池实例详解
2017/04/11 Python
TensorFlow 滑动平均的示例代码
2018/06/19 Python
使用tensorflow实现线性回归
2018/09/08 Python
python pygame实现球球大作战
2019/11/25 Python
利用python3筛选excel中特定的行(行值满足某个条件/行值属于某个集合)
2020/09/04 Python
python中如何打包用户自定义模块
2020/09/23 Python
开业庆典策划方案
2014/02/18 职场文书
计算机专业自荐信
2014/05/24 职场文书
道路交通事故赔偿协议书
2014/10/24 职场文书
2015年营业员工作总结
2015/04/23 职场文书
2015年科学教研组工作总结
2015/07/22 职场文书
初中生活随笔
2015/08/15 职场文书
Pytorch中Softmax和LogSoftmax的使用详解
2021/06/05 Python
Canvas绘制像素风图片的示例代码
2021/09/25 HTML / CSS
关于Mybatis中SQL节点的深入解析
2022/03/19 Java/Android
输入框跟随文字内容适配宽实现示例
2022/08/14 Javascript