详解Vue中this.$nextTick()用法

这篇博客探讨了Vue中`this.$nextTick`和`updated`生命周期钩子的用法。`$nextTick`用于在DOM更新后执行回调,解决数据变化与DOM更新异步问题。例如,在点击按钮后切换输入框显示并尝试聚焦,直接调用`this.$refs.myInp.focus()`无效,因DOM未更新。通过`this.$nextTick`或使用`async/await`结合`$nextTick`,可以在DOM更新后正确聚焦。而`updated`钩子则在DOM更新后触发,适合执行依赖DOM操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

语法:

this.$nextTick( [ callback ] )

用法: 

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

updated用法:由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。当这个钩子被调用时,组件 DOM 已经更新,所以你现在可以执行依赖于 DOM 的操作。

示例: 

下面讲解一个点击按钮是输入框聚焦的示例:

<template>
  <div>
      <input ref="myInp" type="text" placeholder="这是一个输入框" v-if="isShow">
      <button v-else @click="btn">点击我进行搜索</button>
  </div>
</template>

<script>

// 获取到输入框
// 输入框调用事件方法focus()达到聚焦行为
export default {
    data(){
        return {
            isShow: false
        }
    },
    methods: {
        btn(){
            this.isShow = true;
 
            this.$refs.myInp.focus(); // 没有效果
            
            // 原因: data变化更新DOM是异步的
            // 输入框还没有挂载到真实DOM上
            // 解决:
            // this.$nextTick(() => {
            //     this.$refs.myInp.focus()
            // })
        }
        //async btn(){  
        //    this.isShow = true;
        //    
        //    // 扩展: await取代回调函数
        //    // $nextTick()原地返回Promise对象
        //    await this.$nextTick()
        //    this.$refs.myInp.focus()
        //}
    },
     //扩展
    updated(){  
     // this.$refs.myInp.focus()
    
    }
}
</script>

 直接在methods获取DOM调用聚焦方法是没有效果的,更改之后的文本是需要 dom 更新之后才会实现的,就像我们把将要打印输出的代码放在 setTimeout(fn, 0) 中,这时候用this.$nextTick就能合理解决此问题,如果我们想进页面就处于聚焦状态的话就可以使用updated生命周期函数,调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作

 

### Vue2 中 `$nextTick` 方法详解 #### 一、概念理解 在 Vue 2 中,`$nextTick` 是 Vue 实例的一个方法,用于在 DOM 更新之后执行延迟回调。此方法确保在修改数据之后,等待 Vue 完成更新 DOM 再执行某些特定操作,从而避免直接在修改数据后立即操作 DOM 导致的操作不准确或不完整的情况发生[^2]。 #### 二、工作原理 `$nextTick` 的实现基于 JavaScript 的事件循环机制(Event Loop),当调用 `this.$nextTick()` 时,实际上是在当前任务队列后面加入了一个微任务或者宏任务(取决于浏览器环境),这样可以保证在这个新任务被执行前所有的 DOM 更改都已经同步完成并反映到页面上[^3]。 对于现代浏览器而言,Vue 利用了原生 API MutationObserver 来监听 DOM 节点的变化;而对于较旧版本的浏览器,则采用 setTimeout 或者 MessageChannel 等方式作为替代方案来模拟相同的效果[^4]。 #### 三、基本语法结构 ```javascript vm.$nextTick([callback]) // 如果提供了可选参数 callback 函数,则会在 DOM 更新完成后自动触发该函数; // 若未提供,则返回一个 Promise 对象,在 resolve 后表示 DOM 已经被刷新完毕。 ``` #### 四、实际应用场景举例说明 下面通过具体案例展示如何利用 `$nextTick` 解决因异步渲染带来的问题: 假设存在如下场景:点击按钮向列表添加一项内容,并希望立刻获取最新状态下整个 ul 元素的高度值。如果不借助于 `$nextTick`, 那么很可能读取到的是还未更新之前的尺寸信息。 ```html <div id="app"> <ul> <li v-for="(item,index) in items" :key="index">{{ item }}</li> </ul> <button @click="addItem">Add Item</button> </div> <script> new Vue({ el: '#app', data() { return {items: ['a', 'b']} }, methods:{ addItem(){ this.items.push('c'); // 此处使用 $nextTick 确保 dom 已更新 this.$nextTick(() => { console.log(document.querySelector('ul').clientHeight); }); } } }) </script> ``` 上述代码片段展示了如何安全地访问经过更改后的DOM属性而不会遇到潜在的时间差错乱问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值