Vue 3 中的 nextTick 使用详解与实战案例

简介: Vue 3 中的 nextTick 使用详解与实战案例在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。

Vue 3 中的 nextTick 使用详解与实战案例

在 Vue 3 的日常开发中,我们经常需要在数据变化后等待 DOM 更新完成再执行某些操作。此时,nextTick 就成了一个不可或缺的工具。本文将介绍 nextTick 的基本用法,并通过三个实战案例,展示它在表单验证、弹窗动画、自动聚焦等场景中的实际应用。

什么是 nextTick?

在 Vue 3 中,nextTick 是一个异步函数,它会在下次 DOM 更新循环结束之后执行回调。这是因为 Vue 会将响应式数据的更新进行批处理,在当前“tick”中收集所有变化并在下一个“tick”中统一更新 DOM。nextTick 的作用就是等待这个过程结束之后再执行某段逻辑。

基本用法

Composition API 中使用

import { nextTick } from 'vue'

nextTick(() => {
  // DOM 更新完成后执行
})

Options API 中使用

this.$nextTick(() => {
  // DOM 更新完成后执行
})

实战案例一:表单校验后滚动到第一个错误项

在实际开发中,表单校验失败后,如果页面内容较多,用户往往看不到错误提示。这时,我们可以利用 nextTick 等待错误信息渲染完毕后,滚动到第一个出错的字段。

<template>
  <el-form ref="formRef" :model="form" :rules="rules">
    <el-form-item label="姓名" prop="name">
      <el-input v-model="form.name" />
    </el-form-item>
    <el-form-item label="邮箱" prop="email">
      <el-input v-model="https://www.91chuli.com/" />
    </el-form-item>
    <el-button @click="submit">提交</el-button>
  </el-form>
</template>

<script setup>
import { reactive, ref, nextTick } from 'vue'

const formRef = ref()
const form = reactive({ name: '', email: '' })
const rules = {
  name: [{ required: true, message: '请输入姓名' }],
  email: [{ required: true, message: '请输入邮箱' }]
}

function submit() {
  formRef.value.validate((valid, fields) => {
    if (!valid) {
      nextTick(() => {
        const firstError = Object.keys(fields)[0]
        const el = document.querySelector(`[prop="${firstError}"]`)
        if (el) {
          el.scrollIntoView({ behavior: 'smooth', block: 'center' })
        }
      })
    }
  })
}
</script>

实战案例二:弹窗打开后自动聚焦输入框 + 播放动画

弹窗打开时,通常需要自动聚焦第一个输入框,并希望有一个淡入动画。这同样需要 nextTick 保证 DOM 已完全渲染。

<template>
  <el-button @click="openDialog">新增记录</el-button>
  <el-dialog v-model="visible" title="表单" class="fade-dialog">
    <div ref="formBox" class="form-box" :class="{ 'animate-in': animate }">
      <el-input ref="inputRef" v-model="form.name" placeholder="请输入用户名" />
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, nextTick } from 'vue'

const visible = ref(false)
const animate = ref(false)
const inputRef = ref()
const form = reactive({ name: '' })

function openDialog() {
  visible.value = true
  nextTick(() => {
    animate.value = true
    inputRef.value?.focus()
  })
}
</script>

<style scoped>
.fade-dialog .form-box {
  opacity: 0;
  transform: scale(0.9);
  transition: all 0.3s ease;
}
.fade-dialog .form-box.animate-in {
  opacity: 1;
  transform: scale(1);
}
</style>

实战案例三:ECharts 图表在弹窗中初始化

如果你在弹窗或 Tab 页中使用图表(如 ECharts),需要等容器 DOM 显示后再初始化图表,否则图表会渲染失败或大小异常。

<template>
  <el-button @click="openDialog">查看图表</el-button>
  <el-dialog v-model="visible" width="50%">
    <div ref="chartRef" style="height: 400px;"></div>
  </el-dialog>
</template>

<script setup>
import { ref, nextTick, onMounted } from 'vue'
import * as echarts from 'echarts'

const visible = ref(false)
const chartRef = ref(null)
let chartInstance = null

function openDialog() {
  visible.value = true
  nextTick(() => {
    if (!chartInstance) {
      chartInstance = echarts.init(chartRef.value)
    }
    chartInstance.setOption({
      title: { text: '访问量趋势' },
      xAxis: { type: 'category', data: ['一月', '二月', '三月'] },
      yAxis: { type: 'value' },
      series: [{ data: [120, 200, 150], type: 'bar' }]
    })
  })
}
</script>

总结

nextTick 在 Vue 3 中解决的是“响应式数据变更后,需要访问更新后的 DOM”的问题。在以下场景中尤为关键:

表单校验提示后的自动滚动;

弹窗打开后的输入框聚焦;

Tab 页切换后图表初始化;

动态组件挂载后的插件调用。

目录
相关文章
|
5月前
|
JavaScript 前端开发 安全
Vue 3
Vue 3以组合式API、Proxy响应式系统和全面TypeScript支持,重构前端开发范式。性能优化与生态协同并进,兼顾易用性与工程化,引领Web开发迈向高效、可维护的新纪元。(238字)
811 139
|
5月前
|
缓存 JavaScript 算法
Vue 3性能优化
Vue 3 通过 Proxy 和编译优化提升性能,但仍需遵循最佳实践。合理使用 v-if、key、computed,避免深度监听,利用懒加载与虚拟列表,结合打包优化,方可充分发挥其性能优势。(239字)
428 1
|
6月前
|
开发工具 iOS开发 MacOS
基于Vite7.1+Vue3+Pinia3+ArcoDesign网页版webos后台模板
最新版研发vite7+vue3.5+pinia3+arco-design仿macos/windows风格网页版OS系统Vite-Vue3-WebOS。
707 11
|
5月前
|
JavaScript 安全
vue3使用ts传参教程
Vue 3结合TypeScript实现组件传参,提升类型安全与开发效率。涵盖Props、Emits、v-model双向绑定及useAttrs透传属性,建议明确声明类型,保障代码质量。
491 0
|
7月前
|
缓存 前端开发 大数据
虚拟列表在Vue3中的具体应用场景有哪些?
虚拟列表在 Vue3 中通过仅渲染可视区域内容,显著提升大数据列表性能,适用于 ERP 表格、聊天界面、社交媒体、阅读器、日历及树形结构等场景,结合 `vue-virtual-scroller` 等工具可实现高效滚动与交互体验。
718 1
|
7月前
|
缓存 JavaScript UED
除了循环引用,Vue3还有哪些常见的性能优化技巧?
除了循环引用,Vue3还有哪些常见的性能优化技巧?
401 0
|
8月前
|
JavaScript
vue3循环引用自已实现
当渲染大量数据列表时,使用虚拟列表只渲染可视区域的内容,显著减少 DOM 节点数量。
197 0
|
JavaScript 前端开发 缓存
|
6月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
560 2
|
5月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
461 137

热门文章

最新文章