深入了解 Vue.js 中的 nextTick:实现原理

今天我们来聊一聊vue中的nextTick,这是vue.js中的一个异步API,nextTick 的作用是将回调函数延迟到下次 DOM 更新周期之后执行。我们知道,在vue.js中数据是响应式的,当数据发生变化时,对应的DOM也会随着更新,但是DOM的更新并不是同步的,而是异步执行的,因此,在一些情况下,我们需要在DOM更新之后执行一些代码的话,就需要借助nextTick这个方法。

nextTick的功能与效果

话不多说,我们直接上示例,我们来看下面的这一段代码:为了不过于冗长,css省略

vue 复制代码
<template>
  <div>
    <button @click="addList">更新列表</button>
    <ul>
      <li v-for="item in list">{{ item }}</li>
    </ul>
  </div>
</template>

<script setup>
import { nextTick, ref } from 'vue'
const list = ref([])
list.value = [1,2,3,4,5,6,7,8,9,10]
const addList = () => {
  // 一次添加10个元素
  list.value.push(11,12,13,14,15,16,17,18,19,20)
  // 获取指定的元素,要求页面滚动到这个位置
  let lastDom = document.querySelector('li:last-child')
  lastDom.scrollIntoView()
}
</script>

运行之后我们会发现,虽然页面确实是滚动了,但是没有到达我们预期的位置,而是滚动到11就不动了,这是为什么呢?因为DOM的更新是异步的,而获取指定元素和滚动的执行代码是同步的,我们这里想要获取最后一个li,但实际上,DOM还没有更新完成,获取指定元素的代码就开始执行了,所以获取的并不是最后一个元素,自然也就没有达到我们想要的效果。

想要达到我们需要的效果,我们只需要把获取指定元素的代码和滚动的代码放进nextTick的回调中就好了

vue 复制代码
<script setup>
import { nextTick, ref } from 'vue'
const list = ref([])
list.value = [1,2,3,4,5,6,7,8,9,10]
const addList = () => {
  // 一次添加10个元素
  list.value.push(11,12,13,14,15,16,17,18,19,20)
  nextTick(() => {
    // 获取指定的元素,要求页面滚动到这个位置
    let lastDom = document.querySelector('li:last-child')
    lastDom.scrollIntoView()
  })
}
</script>

这样就可以达到我们想要的效果

手写一个简单的nextTick

那么怎么实现nextTick的效果呢,其实我们也可以手写一个简单的nextTick,帮助我们理解nextTick

nextTick接受一个回调函数作为形参,当页面上的DOM更新完成之后,执行回调中的代码

js 复制代码
// 创建一个简单的nextTick
function simpleNextTick(fn) { // 接受一个回调函数作为形参
    let dom = document.documentElement; // 获取文档对象
    let observer = new MutationObserver(() => { // 创建一个观察器 MutationObserver是一个内置的 JavaScript API,可以在 DOM 树中的节点发生变化时触发回调函数
        fn(); // 观察到变化后执行回调函数
    });
    observer.observe(dom, {
        attributes: true,
        childList: true,
        subtree: true
    }); // observe 是MutationObserver 的实例方法,用于观察文档对象的属性、子节点、后代节点变化
}

这样就完成了一个简单的nextTick,只需要将其引入我们的项目中就可以达到效果

相关推荐
whinc21 小时前
JavaScript技术周刊 2026年第18周
javascript
码海扬帆:前端探索之旅21 小时前
深度定制 uni-combox:新增功能详解与实战指南
前端·vue.js·uni-app
谷雨不太卷21 小时前
进程的状态码
java·前端·算法
打小就很皮...21 小时前
基于 Python + LangChain + RAG 的知识检索系统实战
前端·langchain·embedding·rag
whinc21 小时前
JavaScript技术周刊 2026年第17周
javascript
BJ-Giser21 小时前
Cesium 烟雾粒子特效
前端·可视化·cesium
空中海21 小时前
02 ArkTS 语言与工程规范
java·前端·spring