VueJS虽然是数据驱动视图,但是数据并不是马上渲染到视图中,而是在渲染队列中,等待一定时机进行渲染。在这次渲染发生之前,如果获取视图元素的内容,将会得到未改变的内容。解决办法是,等待nextTick()发生再对元素进行获取。
nextTick简单demo
<script setup>
import { ref, nextTick } from 'vue'
const count = ref(0)
async function increment() {
count.value++
// DOM 还未更新
console.log(document.getElementById('counter').textContent) // 0
await nextTick()
// DOM 此时已经更新
console.log(document.getElementById('counter').textContent) // 1
}
</script>
<template>
<button id="counter" @click="increment">{{ count }}</button>
</template>
- 在未nextTick时,DOM元素未更新
- nextTick之后,DOM元素内容更新
当然,也可以使用ref绑定和获取DOM元素:
<script setup>
import { ref, nextTick, onMounted } from 'vue'
const count = ref(0)
const counter = ref()
async function increment() {
count.value++
console.log(counter.value.innerText)
await nextTick()
console.log(counter.value.innerText)
}
</script>
<template>
<button ref="counter" id="counter" @click="increment">{{ count }}</button>
</template>
nextTick业务场景
elementPlus有一个动态渲染tag的组件,当点击New Tag的时候,立即弹出输入框,并且focus输入框。 ElementPlus演练场
此处如果不使用nextTick,inputVisible的值没有同步到输入框上,输入框未渲染出来,无法聚焦。