虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。比如一个新闻滚动的列表项。如果在这里需要操作dom, 应该是等待 Vue 完成更新 DOM之后。

一、新闻滚动列表

1、在created函数中获取后台数据;

2、模板引擎中用v-for生成列表项;

3、调用滚动函数,假设该滚动函数式原生方法写的;

4、什么时候开始调用滚动函数比较合适呢?

二、this.$nextTick()

官方解释:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上。

  1. Vue.component('example', {
  2. template: '<span>{{ message }}</span>',
  3. data: function () {
  4. return {
  5. message: 'not updated'
  6. }
  7. },
  8. methods: {
  9. updateMessage: function () {
  10. this.message = 'updated'
  11. console.log(this.$el.textContent) // => 'not updated'
  12. this.$nextTick(function () {
  13. console.log(this.$el.textContent) // => 'updated'
  14. })
  15. }
  16. }
  17. })

三、新闻滚动列表中的this.$nextTick()放哪里?

  因为数据是根据请求之后获取的,所以应该放到请求的回调函数里面。

四、原理【重点】

前面只是利用一个例子引入话题。

在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,为什么获取不到 DOM呢?

原因:

这里就涉及到 Vue 一个很重要的概念:异步更新队列(JS运行机制 、 事件循环)。

Vue 在观察到数据变化时并不是直接更新 DOM,而是开启一个队列,并缓冲同一事件循环中发生的所有数据改变。

在缓冲时会去除重复数据,从而避免不必要的计算和DOM操作。

然后,在下一个事件循环 tick 中,Vue 刷新队列并执行实际(已去重的)工作。

所以如果用 for 循环来动态改变数据100次,其实它只会应用最后一次改变,如果没有这种机制,DOM就要重绘100次,是一个很大的开销,损耗性能。

例子:

  1. //改变数据
  2. vm.message = 'changed'
  3.  
  4. //想要立即使用更新后的DOM。这样不行,因为设置message后DOM还没有更新
  5. console.log(vm.$el.textContent) // 并不会得到'changed'
  6.  
  7. //这样可以,nextTick里面的代码会在DOM更新后执行
  8. Vue.nextTick(function(){
  9. console.log(vm.$el.textContent) //可以得到'changed'
  10. })

  

五、常见应用

点击按钮显示原本以 v-show = false 隐藏起来的输入框,并获取焦点。

  1. showsou(){
  2. this.showit = true //修改 v-show
  3. document.getElementById("keywords").focus() //在第一个 tick 里,获取不到输入框,自然也获取不到焦点
  4. }
  5.  
  6. //修改
  7. showsou(){
  8. this.showit = true
  9. this.$nextTick(function () {
  10. // DOM 更新了
  11. document.getElementById("keywords").focus()
  12. })
  13. }

  

Vue this.$nextTick原理的更多相关文章

  1. Vue你不得不知道的异步更新机制和nextTick原理

    前言 异步更新是 Vue 核心实现之一,在整体流程中充当着 watcher 更新的调度者这一角色.大部分 watcher 更新都会经过它的处理,在适当时机让更新有序的执行.而 nextTick 作为异 ...

  2. Vue异步更新机制以及$nextTick原理

    相信很多人会好奇Vue内部的更新机制,或者平时工作中遇到的一些奇怪的问题需要使用$nextTick来解决,今天我们就来聊一聊Vue中的异步更新机制以及$nextTick原理 Vue的异步更新 可能你还 ...

  3. 深度解析 Vue 响应式原理

    深度解析 Vue 响应式原理 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还是进 ...

  4. Vue视图渲染原理解析,从构建VNode到生成真实节点树

    前言 在 Vue 核心中除了响应式原理外,视图渲染也是重中之重.我们都知道每次更新数据,都会走视图渲染的逻辑,而这当中牵扯的逻辑也是十分繁琐. 本文主要解析的是初始化视图渲染流程,你将会了解到从挂载组 ...

  5. 基于源码分析Vue的nextTick

    摘要:本文通过结合官方文档.源码和其他文章整理后,对Vue的nextTick做深入解析.理解本文最好有浏览器事件循环的基础,建议先阅读上文<事件循环Event loop到底是什么>. 一. ...

  6. Vue双向绑定原理,教你一步一步实现双向绑定

    当今前端天下以 Angular.React.vue 三足鼎立的局面,你不选择一个阵营基本上无法立足于前端,甚至是两个或者三个阵营都要选择,大势所趋. 所以我们要时刻保持好奇心,拥抱变化,只有在不断的变 ...

  7. vue中nextTick

    vue中nextTick可以拿到更新后的DOM元素 如果在mounted下不能准确拿到DOM元素,可以使用nextTick 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue ...

  8. 深入浅出 - vue变化侦测原理

    废话真多!!! 其实在一年前我已经写过一篇关于 vue响应式原理的文章,但是最近我翻开看看发现讲的内容和我现在心里想的有些不太一样,所以我打算重新写一篇更通俗易懂的文章. 我的目标是能让读者读完我写的 ...

  9. vue双向绑定原理分析

    当我们学习angular或者vue的时候,其双向绑定为我们开发带来了诸多便捷,今天我们就来分析一下vue双向绑定的原理. 简易vue源码地址:https://github.com/jiangzhenf ...

随机推荐

  1. SQL 2008建一个job

    原文地址:http://blog.csdn.net/htl258/article/details/5543694 --  Author : htl258(Tony)--  Date   : 2010- ...

  2. fiddler之编辑请求(composer)-发包

    在需要针对接口进行发包操作时,可以使用composer标签,去编辑请求内容,进行请求. 界面显示如下: 1.Parsed 在该分页中,选择请求方法.设置请求地址和协议版本,上部分为请求的头信息.下半部 ...

  3. 各种CNN模型

    Resnet: model_urls = { 'resnet18': 'https://download.pytorch.org/models/resnet18-5c106cde.pth', 'res ...

  4. Anaconda版本

    1. Anaconda各种版本 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 2. 多个Python环境 conda info -e c ...

  5. Docker Toolbox虚拟机文件地址修改 以及镜像加速

    Docker Toolbox虚拟机文件地址修改  默认情况下,docker-machine创建的虚拟机文件,是保存在C盘的C:\Users\用户名\.docker\machine\machines\d ...

  6. .net core 学习小结之 Cookie-based认证

    在startup中添加授权相关的管道 using System; using System.Collections.Generic; using System.Linq; using System.T ...

  7. ubuntu server安装的一些坑

    [没有root用户] ubuntu server安装的时候要你新建一个用户,安装完成后,你需要手动开启root. $ sudo passwd root 输入你当前用户的密码 输入你希望的root用户的 ...

  8. C++智能指针 原理、使用与实现

    目录 理解智能指针的原理 智能指针的使用 智能指针的设计和实现 1.智能指针的作用 C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理.程序员自己管理堆内存可以提高了程序 ...

  9. java锁的使用

    1 synchronize和ReentrantLock synchronize锁是jvm内置的锁,它锁的是synchronize所在的类的对象,要同步那么就只能有一个对象. ReentrantLock ...

  10. Spring Boot 2.2.0 正式发布,支持 JDK 13!

    Java技术栈 www.javastack.cn 优秀的Java技术公众号 推荐阅读: Spring Boot 2.2.0 正式发布了,可从 repo.spring.io 或是 Maven Centr ...