让你一看就明白的$nextTick讲解

目录
  • 1.功能描述
  • 2.父组件
  • 3.子组件NextTick.vue
  • 4为什么是undefined
  • 5.将v-if更改为v-show可以获取焦点吗?
  • 6.实际结果
  • 7.将组件变成页面可以获取焦点吗?
  • 8.为什么会有$nextTick
  • 9.Vue.nextTick和this.$nextTick差别
  • 10.使用 nextTick的一个小技巧
  • 总结

1.功能描述

今天我们要实现这个一个小功能;页面渲染完成后展示一个div元素;当点击这个div元素后;div元素消失;出现一个input元素;并且input元素聚焦,想必大家觉得简单,我们一起来看看~

创建一个组件,组件名称NextTick.vue;

在页面中引入注册

2.父组件

<template>
  <div>
    <next-tick></next-tick>
  </div>
</template>

<script lang="ts">
import NextTick from "../components/NextTick.vue"
export default {
  name:"About",
  components:{
    NextTick
  },
}
</script>

3.子组件NextTick.vue

<template>
    <div>
        <div>我是组件</div>
        <div v-if="flag" class="sun" @click="handerClick">显示input</div>
        <input v-else ref="inputRef" class="yuelaing"/>
    </div>
</template>
<script>
export default {
    data(){
        return{
            flag:true,
        }
    },
    methods: {
        handerClick(){
            this.flag=false;
            this.$refs.inputRef.focus();
        },
    },
}
</script>

4为什么是undefined

this.flag=false;
this.$refs.inputRef.focus();

当执行页面操作的时候,this.$refs.inputRef.focus();

是需要消耗时间的(还没有还得及刷新;还是旧的页面)

此时还没有获取到dom元素。

所以会报错。

解决方式1:

因此只要让页面能够获取元素就行;使用setTimeout

setTimeout(()=>{
      this.$refs.inputRef.focus();
},100)

这样来处理这个问题,是可以的;

但是显得非常的不专业;

解决方式2:

//当组件根据最新的data数据,重新在视图上完成渲染后,在执行里面的函调函数
this.$nextTick(()=>{
    this.$refs.inputRef.focus();
})

5.将v-if更改为v-show可以获取焦点吗?

有人说:因为v-if是动态创建和销毁;在创建和销毁的过程中,是需要时间的!所以才会使用v-if获取不到元素节点,用v-show就可以避免。

感觉说的有点道理?

我们尝试一下将v-if换成v-show

<template>
    <div>
        <div>我是组件</div>
        <div v-show="flag" class="sun" @click="handerClick">显示input</div>
        <input v-show="!flag" ref="inputRef" class="yuelaing"/>
    </div>
</template>
<script>
export default {
    data(){
        return{
            flag:true,
        }
    },
    methods: {
        handerClick(){
            this.flag=false;
            console.log( this.$refs.inputRef);
            this.$refs.inputRef.focus();
        },
    },
}
</script>

6.实际结果

我们发现虽然是页面没有报错,但是还没有聚焦;改为v-show明显也不能够解决这个问题

之所以会出现这个问题,是因为子组件中将this.flag=false后,立刻去执行了下面的代码

this.$refs.inputRef.focus();

而在执行的时候,视图还没没有来得及刷新;还是旧的页面,此时还不能够获取到dom元素,因此出现了undefined;也就是为什么我们加上延时后就可以聚焦了;

当组件根据最新的data数据,重新在视图上完成渲染后,在执行里面的函调函数

这就是$nextTick的基本用法

this.$nextTick(()=>{
    this.$refs.inputRef.focus();
})

7.将组件变成页面可以获取焦点吗?

又有人说:因为是子组件,子组件比父组件后渲染。所以没有获取到元素节点。

这也是理由....

感觉还没有上一个小伙伴说的对,为了解决疑惑。我们决定将子组件变成页面在看看

<template>
  <div>
    <div>我是组件</div>
    <div v-show="flag" class="sun" @click="handerClick">显示input</div>
    <input v-show="!flag" ref="inputRef" class="yuelaing"/>
  </div>
</template>
<script>
export default {
  data(){
    return{
        flag:true,
    }
  },
  methods: {
      handerClick(){
        this.flag=false;
        this.$refs.inputRef.focus();
      },
  },
}
</script>

我们发现仍然不可以;这就充分说明了:更新data的数据后,vue并不是实时更新的。

数据更新到显示到页面有时间差,我们在时间差内调用页面数据,当然获取不到。

也就是说:Vue在更新 DOM 时是异步执行的

8.为什么会有$nextTick

之所以会有$nextTick;因为在vue中数据发生变化后;视图上的dom并不会立刻去跟新;dom的跟新是需要时间的

下面我们通过一个小实验来看一下

<template>
  <div>
    <div ref="unique">
      <h1>{{ cont }}</h1>
    </div>
    <div  class="sun" @click="handerClick">改变值</div>
  </div>
</template>
<script>
export default {
  data(){
    return{
      cont:'我是默认值'
    }
  },
  methods: {
      handerClick(){
        this.cont='我改变了默认值';
        console.log('1==>',this.$refs.unique.innerText);
        this.$nextTick(()=>{
          console.log('2==>',this.$refs.unique.innerText);
        })
      },
  },
}
</script>

我们发现,第一次的值和第二次的值,是不一样的;因为视图上dom的跟新是需要之间的;我们在这个之间差内去获取元素值;仍然是旧值;所以第一次的值是最初的值;第二次的值才是改变后的值;

由于我们希望跟新数据后,仍然可以立刻获取dom上的值

所以vue提供了$nextTick就可以解决这个问题

9.Vue.nextTick和this.$nextTick差别

Vue.nextTick是全局方法

this.$nextTick( [callback] ) 是实例方法。

我们都知道一个页面可以有多个实例,也就是说this.$nextTick可以精确到某个实例上。其实本质上两个是一样的。
只是一个是全局,一个是精确到某一个实例。精确度不一样而已。

10.使用 nextTick的一个小技巧

我们都知道在生命周期mounted渲染的时候,不能百分百保证所有的子组件都能够被渲染,因此我们可以在mounted里面使用 this.$nextTick,这样就能保证所有的子组件都能被渲染到。

mounted钩子在服务器端渲染期间不被调用。

mounted: function () {
  this.$nextTick(function () {
    //在数据发生变化,
    //重新在视图上完成渲染后,在执行里面的方法
    //这一句话等同与:
   //将回调延迟到下次 DOM 更新循环之后执行
   //等同于:在修改数据之后,然后等待 DOM 更新后在执行
  })
}

总结

到此这篇关于$nextTick的文章就介绍到这了,更多相关$nextTick讲解内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue中$nextTick的用法讲解

    vue是非常流行的框架,他结合了angular和react的优点,从而形成了一个轻量级的易上手的具有双向数据绑定特性的mvvm框架.本人比较喜欢用之.在我们用vue时,我们经常用到一个方法是this.$nextTick,相信你也用过.我常用的场景是在进行获取数据后,需要对新视图进行下一步操作或者其他操作时,发现获取不到dom.因为赋值操作只完成了数据模型的改变并没有完成视图更新.在这个时候我们需要用到本章介绍的函数. 虽然 Vue.js 通常鼓励开发人员沿着"数据驱动"的方式思考,避免

  • vue2.0$nextTick监听数据渲染完成之后的回调函数方法

    vue里面本身带有两个回调函数: 一个是`Vue.nextTick(callback)`,当数据发生变化,更新后执行回调. 另一个是`Vue.$nextTick(callback)`,当dom发生变化,更新后执行的回调. 栗子: ... <ul id="demo"> <li v-for="item in list">{{item}}</div> </ul> ... new Vue({ el:'#demo', data:

  • VUE异步更新DOM - 用$nextTick解决DOM视图的问题

    VUE异步更新DOM 首先,Vue 在更新 DOM 时是异步执行的! 所以只要侦听到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据变更.如果同一个 watcher 被多次触发,只会被推入到队列中一次.这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作是非常重要的.然后,在下一个的事件循环"tick"中,Vue 刷新队列并执行实际 (已去重的) 工作.Vue 在内部对异步队列尝试使用原生的 Promise.then.MutationObserver 和

  • 详解vue指令与$nextTick 操作DOM的不同之处

    异步更新队列 可能你还没有注意到,Vue 异步执行 DOM 更新.只要观察到数据变化,Vue 将开启一个队列,并缓冲在同一事件循环中发生的所有数据改变.如果同一个 watcher 被多次触发,只会被推入到队列中一次.这种在缓冲时去除重复数据对于避免不必要的计算和 DOM 操作上非常重要.然后,在下一个的事件循环"tick"中,Vue 刷新队列并执行实际 (已去重的) 工作.Vue 在内部尝试对异步队列使用原生的 Promise.then 和 MessageChannel,如果执行环境不

  • 详解vue中$nextTick和$forceUpdate的用法

    1.$nextTick vm.$nextTick( [callback] ) this.$nextTick()将回调延迟到下次 DOM 更新循环之后执行,在修改数据之后立即使用它,然后等待 DOM 更新.它跟全局方法 Vue.nextTick 一样,不同的是回调的 this 自动绑定到调用它的实例上. 应用场景: 1. 在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中. 2. 因为在created()钩子函数执行的时候DOM 其实并未

  • Vue中this.$nextTick的作用及用法

    Vue实现响应式后DOM的变化 data对象中数据改变是如何追踪的? vue将遍历data对象中所有的属性,并通过 Object.defineProperty 把这些属性全部转为 getter/setter:但是我们是没有办法看到 getter/setter的,但是在内部它们让 Vue 能够追踪依赖,在属性被访问和修改时通知变更. 每个组件都对应一个 watcher 实例,它会在组件渲染的过程中把"接触"过的数据属性记录为依赖.之后当依赖项的 setter 触发时,会通知 watche

  • 详解Vue + Vuex 如何使用 vm.$nextTick

    vm.$nextTick 简单说,因为DOM至少会在当前tick里面的代码全部执行完毕再更新.所以不可能做到在修改数据后并且DOM更新后再执行,要保证在DOM更新以后再执行某一块代码,就必须把这块代码放到下一次事件循环里面,比如setTimeout(fn, 0),这样DOM更新后,就会立即执行这块代码. //改变数据 vm.message = 'changed' //想要立即使用更新后的DOM.这样不行,因为设置message后DOM还没有更新 console.log(vm.$el.textCo

  • 全面解析Vue中的$nextTick

    当在代码中更新了数据,并希望等到对应的Dom更新之后,再执行一些逻辑.这时,我们就会用到$nextTick funcion callback(){ //等待Dom更新,然后搞点事. } $nextTick(callback): 官方文档对nextTick的解释是: 在下次 DOM 更新循环结束之后执行延迟回调.在修改数据之后立即使用这个方法,获取更新后的 DOM. 那么,Vue是如何做的这一点的,是不是在调用修改Dom的Api之后(appendChild, textContent = "xxxx

  • 让你一看就明白的$nextTick讲解

    目录 1.功能描述 2.父组件 3.子组件NextTick.vue 4为什么是undefined 5.将v-if更改为v-show可以获取焦点吗? 6.实际结果 7.将组件变成页面可以获取焦点吗? 8.为什么会有$nextTick 9.Vue.nextTick和this.$nextTick差别 10.使用 nextTick的一个小技巧 总结 1.功能描述 今天我们要实现这个一个小功能:页面渲染完成后展示一个div元素:当点击这个div元素后:div元素消失:出现一个input元素:并且input

  • Vue异步更新机制及$nextTick原理的深入讲解

    目录 前言 Vue的异步更新 DOM更新是异步的 DOM更新还是批量的 事件循环 执行过程 源码深入 异步更新队列 nextTick $nextTick 总结 一般更新DOM是同步的 既然更新DOM是个同步的过程,那为什么Vue却需要借用$nextTick来处理呢? 为什么优先使用微任务? 总结 前言 相信很多人会好奇Vue内部的更新机制,或者平时工作中遇到的一些奇怪的问题需要使用$nextTick来解决,今天我们就来聊一聊Vue中的异步更新机制以及$nextTick原理 Vue的异步更新 可能

  • 大白话讲解JavaScript的Promise

    去年6月份, ES2015正式发布(也就是ES6,ES6是它的乳名),其中Promise被列为正式规范.作为ES6中最重要的特性之 一,我们有必要掌握并理解透彻.本文将由浅到深,讲解Promise的基本概念与使用方法.  ES6 Promise 先拉出来遛遛 复杂的概念先不讲,我们先简单粗暴地把Promise用一下,有个直观感受.那么第一个问题来了,Promise是什么玩意呢?是一个类?对象?数组?函数? 别猜了,直接打印出来看看吧,console.dir(Promise),就这么简单粗暴. 这

  • javascript帧动画(实例讲解)

    前面的话 帧动画就是在"连续的关键帧"中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成的动画.由于是一帧一帧的画,所以帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容.本文将详细介绍javascript帧动画 概述 [分类] 常见的帧动画的方式有三种,包括gif.CSS3 animation和javascript git和CSS3 animation不能灵活地控制动画的暂停和播放.不能对帧动画做更加灵活地扩展.另外,gif图不能捕捉动画完成的事件.所以,

  • 实例讲解vue源码架构

    下载 去github上下载Vue https://github.com/vuejs/vue npm install npm run dev 运行起来 rollup + flow vue使用使用rollup打包,flow规范数据类型 rollup可以先用webpack套用,读起来差不多,时间有限,毕竟只有5分钟,这个就不用去看rollup文档了 入口 打开package.json 我们看scripts配置 "dev": "rollup -w -c scripts/config.

  • vue.js刷新当前页面的实例讲解

    在我们修改过页面的某些数据后,通过想要把页面刷新一下,看看修改后的结果.由于vue的存在,页面是不会自动刷新的,需要我们手动进行操作.在vue里有三种刷新方法,最推荐的就是组合控制法,另外另种方法也会分享给大家学习,下面我们一起来看看vue如何刷新页面吧. 1.强制刷新 window.location.reload() 原生 js 提供的方法: this.$router.go(0),vue 路由里面的一种方法: 这两种方法都可以达到页面刷新的目的,简单粗暴,但是用户体验不好,相当于按 F5 刷新

  • Vue nextTick的原理解析

    使用过Vue的小伙伴们都知道,Vue里的nextTick可以获取到更新后的DOM, 今天我就来讲解下nextTick里面究竟做了什么? 开始讲解前,我们需要知道了解一个概念,那就是Event Loop Event Loop Event Loop翻译过来就是事件循环, 一个Event Loop会包括一个或多个task队列,持续线程会从队列中取出最早进入队列的任务进行执行,被取出的任务就叫做macroTask(宏任务), 每个macroTask都有一个任务源, 每个macroTask处理完之后就从队

  • vue中4个自定义指令讲解及实例用法

    四个实用的vue自定义指令 1.v-drag 需求:鼠标拖动元素 思路: 元素偏移量 = 鼠标滑动后的坐标 - 鼠标初始点击元素时的坐标 + 初始点击时元素距离可视区域的top.left. 将可视区域作为边界,限制在可视区域里面拖拽.[相关推荐:<vue.js教程>] 代码: Vue.directive('drag', { inserted(el) { let header = el.querySelector('.dialog_header') header.style.cssText +=

  • vue.js踩坑之ref引用细节点讲解

    目录 ref引用细节点讲解 要点简介:[ 见下文案例 ] 通过ref引用的形式,来操作DOM 步骤如下 重要代码如下 ref引用及插槽 ref引用 ref引用DOM元素 ref引用组件实例 实现标签的按需切换 插槽 匿名插槽 具名插槽 作用域插槽 ref引用细节点讲解 vue.js组件之H5页面,DOM标签或者组件中,通过ref="自定义name名称"引用的细节点 要点简介:[ 见下文案例 ] 使用is=" "解决H5出现的标签解析bug . 子组件中 使用data

随机推荐