Vue中如何定位v-for循环渲染的元素并获取其展开后的高度
Vue中v-for循环内元素定位方案
结论:可以实现,你之前的写法存在错误
你尝试的对象语法绑定ref是无效的,该语法仅适用于class和style属性,ref属性不支持这类动态绑定规则。
推荐实现方案
方案1:绑定同个ref统一收集后匹配
给v-for循环的所有元素绑定同一个ref名,Vue会自动将所有匹配的DOM元素存入数组中,展开时通过标识匹配对应元素即可,Vue2/Vue3通用:
<div v-for="(item, index) in list" :key="item.name" v-show="foo === 'foo_' + item.name" ref="barList" :data-name="item.name" > <!-- 元素内容 --> </div>
触发展开后,遍历ref集合匹配对应元素即可:
- Vue2写法:
this.$refs.barList.find(el => el.dataset.name === 当前展开的name值) - Vue3写法:提前声明
const barList = ref([]),然后取barList.value.find(el => el.dataset.name === 当前展开的name值)
方案2:展开事件直接传递DOM
如果展开操作是通过点击等交互触发,可以直接在事件中传递$event拿到目标元素,不需要依赖ref:
<div v-for="item in list" :key="item.name" @click="handleExpand($event, item)" > <div v-show="foo === 'foo_' + item.name" class="expand-content"> <!-- 内容 --> </div> </div>
function handleExpand(e, item) { const expandEl = e.currentTarget.querySelector('.expand-content') // 直接读取高度即可 }
方案3:动态拼接ref名精准定位
你也可以给每个元素绑定带唯一标识的ref名,需要用的时候直接拼接名字获取:
<div v-for="item in list" :key="item.name" v-show="foo === 'foo_' + item.name" :ref="`bar_${item.name}`" > </div>
取元素时直接按拼接后的名字查找即可:
- Vue2:
this.$refs[bar_${当前展开的name值}] - Vue3:
refList[bar_${当前展开的name值}].value[0],Vue3动态ref默认返回数组,取第一项即为真实DOM
注意事项
v-show隐藏的元素仅为display: none,依然会渲染到DOM中,读取高度时要确保时机在元素切换为显示、DOM更新完成后,可以用$nextTick包裹读取逻辑,避免拿到高度为0的错误结果。
内容的提问来源于stack exchange,提问作者ltm
相关产品推荐
相关产品推荐

