卖坚果的怪叔叔 卖坚果的怪叔叔
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
首页 › 技术 › Vue3 Ref获取节点返回顺序不一致。

Vue3 Ref获取节点返回顺序不一致。

坚果大叔
2024-04-15 13:14:49技术阅读 5,059

项目中使用 vue3的 ref 功能来获取当前组件暴露的api。但是在控制台打印的dom数组的时候却和实际页面中的节点顺序不一致。这就导致可怜我在页面点了获取排在第一个的数据。但是给我返回的却是第三个。代码如下:

<div @click="down"> 下载</div>

<template v-for="(list, index) in data" :key="list.id">
    <MapArea 
        ref="refMaps"
        :data="dataList">
    </MapArea>
</template>

const refMaps = ref([])

funciton down() {
    console.log(refMaps.value)
}

在页面初始化进来的时候。点击下载打印出来的数据是和dom节点里面的数据一致的。只有在我切换不同数据源之后。比如当前初始化的是三条数据,切换到两条数据。在切换回来的时候打印的时候顺序就颠倒了。

十分的奇怪。

而且只要切换后。打印的dom顺序就一直保持颠倒的状态不会改变。

寻找解决方案。

1、第一种想到的是因为异步数据加载导致dom更新的顺序变了。但是很快被否了,因为点击打印的操作已经在 dom 更新结束。
2、使用 nextTick
funciton down() {
    nexttick(() => {
        console.log(refMaps.value)
    })
}

发现其实没有啥用。因为dom 已经更新结束。

3、使用js的原生方法。

首先给ref替换成 class。然后通过原生 js来获取相同的 class并指定获取第几个 class的 dom 来实现。

// 获取单个具有指定 class 的元素
const singleElement = document.querySelector('.my-class');

// 如果需要获取所有具有指定 class 的元素,可以使用 querySelectorAll
const allElements = document.querySelectorAll('.my-class');

// 然后可以对获取到的元素进行操作
if (singleElement) {
  console.log('Found single element:', singleElement);
  // 对 singleElement 进行操作...
}

if (allElements.length > 0) {
  console.log('Found multiple elements:', allElements);
  // 遍历 allElements 进行操作...
  allElements.forEach((el) => {
    // 对每个 el 进行操作...
  });
}

这种方法其实相对比较保险。因为相对于上面 ref带来的不确定性。虽然在多次测试中返回的结果都是倒序返回。完全可以用数组方法 reverse()。但是并不能确定他的顺序一定是颠倒的。所以 pass。

4、将 ref的赋值从默认改为动态赋值。
# 原来的
<MapArea 
    ref="refMaps"
    :data="dataList">
</MapArea>

# 改变后
<MapArea 
    :ref="(el) => setItemRef(el, index)"
    :data="dataList">
</MapArea>

let itemRefs = []
const setItemRef = (el, index) => {
    if (el) {
      itemRefs[index] = (el)
    }
}

这样就可以解决这个莫名其妙的问题。到这里其实还是没有找到问题发生的本质,因为之前没有遇到过当前场景。

其实在 Vue3 中,当你使用 ref 来引用 DOM 元素并遍历节点数组时,返回的节点顺序可能与在浏览器中渲染的顺序相反。这可能是因为 Vue3 在渲染和更新 DOM 时使用了虚拟 DOM 和响应式系统的机制。

而虚拟 DOM 和响应式系统通常会在渲染期间对节点进行优化和重新排序,以提高性能并确保 DOM 的一致性。因此,可能会出现在遍历节点数组时返回的顺序与在浏览器中实际渲染的顺序不同的情况。

赞赏 赞(4)
清明假期~
上一篇
嗦鸭头~
下一篇
在小程序中查看

这是个😊,挣点服务器费用😜

热门文章
隔离第12天。
门前的空地,转眼又绿了
三度胃镜有感
Vue响应式原理
清明小假期!
简单!三步实现微信消息同步!!
专题标签
agent (1) CSS (15) dom (1) Es6入门系列 (14) Git (3) html (1) iview (1) JavaScript (9) js (4) Lif (1) Node (4) pyecharts (1) Python (10) ref (1) scriptable (1) Skill (1) vsCode (1) vue (4) wordpress (2) 三月 (1) 上海 (1) 假期 (1) 其他分享 (3) 前端两三问 (15) 古镇 (1) 外滩 (1) 对象 (1) 小程序 (5) 年度总结 (6) 年终总结 (1) 微信机器人 (4) 打字机 (1) 技术 (1) 日常问题 (8) 日常问题记录 (1) 春天 (2) 服务器 (2) 海族馆 (1) 生活 (8) 网上国网 (1) 记录 (3) 通勤 (1) 重学JavaScript (11) 面试题 (10) 🌸 (1)
什么是Agent?
2026-08-15 23:49:12
431 0 2
什么是 Skill?
2026-08-12 21:32:42
348 1 0
失业在家,我给小朋友做了一个练字小程序!
2026-08-07 16:21:52
690 10 1
上线8年,15万用户的小程序,一共赚了多少钱?
2026-05-30 18:01:24
4,683 4 0
4
  • 4
博主

一位佛系的前端开发者,略通摄影,乐于尝试新事物,热衷于美食。

友链
故事胶片
公众号
坚果大叔 执行上下文 卖坚果的怪叔叔 Dacking
Copyright © 2017-2026 卖坚果的怪叔叔

开往-友链接力

萌ICP备20230818号

苏ICP备18048410号-3
  • 首页
  • 生活
  • 技术
  • 记录
  • 工具箱
  • 关于我
# CSS # # JavaScript # # vue # # 微信 # # 生活 #
坚果大叔
345
文章
171
评论
432
喜欢