案例场景
场景描述:现在左边的线条长度需要根据右边盒子的高度进行动态变化
实践代码案例
HTML部分
<div v-for="(device, index) in devices" :key="index">
<!-- 动态设置 .left-bar 的高度 -->
<div class="left-bar" :style="{ height: `${contentHeights[index] || 30}px` }"></div>
<div :ref="(el) => { contentRefs[index] = el as HTMLElement }">
<span>设备编号:{{ device.code }}</span>
<span>异常信息:{{ device.info }}</span>
</div>
</div>
JS部分
import { reactive, toRefs, ref, onMounted, watch, nextTick } from 'vue';
interface Device {
code: string;
status: string;
info: string;
}
const state = reactive({
devices:[
{
code: 'JS23053001',
status: '异常',
info: '提升激光仪通讯故障 提升激光仪通讯故障 备用(从站数据故障) 备用(从站数据故障)'
},
{
code: 'JS23053002',
status: '异常',
info: '货物左超 过载保护 断绳保护 超速保护 行走超限 升降超限'
},
{ code: 'JS23053003', status: '正常', info: '正常' },
{ code: 'JS23053003', status: '正常', info: '正常' },
{
code: 'JS23053003',
status: '异常',
info: '行走变频器通讯故障 行走变频器通讯故障 货叉1变频器通讯故障'
}
],
});
const { devices } = toRefs(state);
// 用于存储每个 content 元素的引用
const contentRefs = ref<(HTMLElement | null)[]>([]);
// 存储每个设备的 .content 元素的高度
const contentHeights = ref<number[]>([]);
// 更新每个设备的 content 高度
const updateContentHeight = () => {
contentHeights.value = contentRefs.value.map(contentRef => {
// 获取每个 content 元素的高度
return contentRef ? contentRef.clientHeight : 0;
});
};
// 监听设备列表变化,重新更新高度
watch(() => state.devices, () => {
nextTick(() => updateContentHeight()); // 确保 DOM 渲染完成后获取高度
}, { immediate: true });
Style部分(left-bar)
.device-item .left-bar {
width: 2px; // 宽度
margin-right: 0.2rem; // 距离
}
注意:
- 使用 nextTick 确保 DOM 渲染完成后再更新 contentHeights。这能保证获取到准确的高度信息
- 给 .left-bar 设置一个默认高度(例如 30px)来确保它始终可见,即使计算出来的高度是 0 时。你可以调试默认高度,并逐步确保 contentHeights 数组能够正常更新
- contentRefs 是一个数组,用来存储每个 .content 的引用。由于 v-for 渲染的组件是异步的,可能 contentRefs 没有及时更新,导致没有正确获取到每个 .content 的高度