Vue中更新响应式数据后直接获取DOM节点报错的解决办法
解决Vue3中onMounted内直接查询DOM元素报错的问题
问题原因
Vue的响应式DOM更新是异步的。当你在onMounted里给nodes添加新数据后,Vue不会立刻将对应的DOM元素渲染到页面上,这时候直接调用DOM查询操作会因为元素未生成而报错。
解决方法
方法1:用nextTick等待DOM更新完成
nextTick会在Vue完成DOM更新后执行回调,确保你能获取到最新的DOM结构:
<template> <div ref="nodesData"> <div v-for="(item, index) in nodes" :key="index" :id="item.id"> {{ item.id }} </div> <div> {{ result.id || '*' }} - this is id </div> </div> </template> <script setup> import { onMounted, ref, nextTick } from 'vue' const nodesData = ref(null) const nodes = ref([]) const result = ref('') onMounted(async () => { nodes.value.push({ id: 'test-id', }) // 等待DOM更新完成后再查询 await nextTick() result.value = nodesData.value.querySelector(`#${nodes.value[0].id}`) }) </script>
方法2:直接给v-for元素绑定ref(更推荐)
避免手动查询DOM,直接通过ref数组获取v-for渲染的元素,这是更符合Vue设计理念的写法:
<template> <div ref="nodesData"> <div v-for="(item, index) in nodes" :key="index" :id="item.id" ref="nodeItems"> {{ item.id }} </div> <div> {{ result.id || '*' }} - this is id </div> </div> </template> <script setup> import { onMounted, ref, nextTick } from 'vue' const nodesData = ref(null) const nodes = ref([]) const nodeItems = ref([]) // 存储v-for元素的ref数组 const result = ref('') onMounted(async () => { nodes.value.push({ id: 'test-id', }) await nextTick() // 直接从ref数组中取目标元素 result.value = nodeItems.value[0] }) </script>
补充说明
onMounted执行时组件的根DOM已经挂载,所以nodesData.value理论上不会为null,但新增的v-for元素是修改响应式数据后异步渲染的,必须等待DOM更新完成才能获取到。优先使用ref绑定的方式,能避免手动操作DOM带来的潜在问题,代码也更易维护。
内容的提问来源于stack exchange,提问作者SefaUn
相关产品推荐
相关产品推荐

