You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3组合式API:获取激活元素高度失败,如何传递高度至点击元素?

问题解决方法

核心问题

你用单个ref绑定循环里的多个DOM元素,这会导致contentRefs最终只指向最后一个渲染的元素,根本拿不到当前点击元素的高度;同时你也没有专门的变量存储上一个激活元素的高度,无法传递给下一个被点击的元素。

修正后的代码

<script lang="ts" setup>
import { ref, reactive, nextTick } from "vue";

defineProps<{
  content: Array<{ title: string; content: string }>;
}>();

// 改用数组Ref存储所有内容区域的DOM元素
const contentRefs = ref<HTMLDivElement[]>([]);
const isToggled = reactive<{ value: number | null }>({ value: null });
// 存储上一个激活元素的高度
const savedHeight = ref(0);

const handleClick = async (index: number) => {
  // 如果之前有激活的元素,先保存它的高度
  if (isToggled.value !== null && isToggled.value !== index) {
    const prevElement = contentRefs.value[isToggled.value];
    if (prevElement) {
      await nextTick(); // 等待DOM更新完成,确保获取的高度准确
      savedHeight.value = prevElement.scrollHeight;
    }
  }
  // 切换当前激活项的状态
  isToggled.value = isToggled.value === index ? null : index;
};
</script>

<template>
  <div 
    v-for="(item, index) in content" 
    class="accordion" 
    :class="{ open: isToggled.value === index }" 
    :key="index"
  >
    <div @click="() => handleClick(index)">{{ item.title }}</div>
    <div 
      :ref="el => el && contentRefs.push(el)" 
      :style="{ 
        minHeight: isToggled.value === index 
          ? `${savedHeight.value || contentRefs.value[index]?.scrollHeight || 0}px` 
          : '0' 
      }"
    >
      {{ item.content }}
    </div>
  </div>
</template>

关键调整说明

  • 数组Ref替代单个Ref:循环中每个内容区域的DOM会被收集到contentRefs数组里,通过索引可以精准获取对应元素的DOM,解决了单个Ref覆盖的问题。
  • 保存前序元素高度:点击新元素时,先获取上一个激活元素的scrollHeight并存储,nextTick确保DOM渲染完成,避免获取到不准确的高度值。
  • 高度应用逻辑:当前元素激活时,优先使用保存的前序元素高度;如果是第一次激活或无保存高度,则使用自身的scrollHeight。

内容的提问来源于stack exchange,提问作者Patrick

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 20:05:44