我有一些使用v-for渲染的元素 每个元素包含文本和按钮 只有当文本溢出div的高度时,我才需要显示按钮
<div v-for="el in elements" :key="el.id">
<span>{{ el.text }}</span>
<button>Click me</button>
</div>
明显的解决方案是使用v-if,但我应该基于什么来判断? 我需要计算文本的高度,并决定是否显示按钮 因此,我需要使用refs来引用divs,并使用函数来确定是否显示:
<template>
<button @click="addDiv"> 点击添加div </button>
<div v-for="(el, index) in elements" :key="el.id">
<span ref="items">{{ el.text }}</span>
<button v-if="showButton(index)">Click me</button>
</div>
</template>
<script setup lang="ts">
//imports
const elements = ref([]);
const addDiv = function() {
elements.value.push({ text: "测试", id: Date.now() })
}
const items = ref();
const showButton = function (index) {
const item = items.value[index] as HTMLElement;
return item.scrollHeight > item.offsetHeight
}
</script>
但我发现问题是items与DOM不同步。所以很明显,DOM是异步更新的,这就是为什么我的数据有点晚
所以我决定在我的showButton函数中添加nextTick(),但它开始返回Promise,这导致v-if始终为true
<template>
<button @click="addDiv"> 点击添加div </button>
<div v-for="(el, index) in elements" :key="el.id">
<span ref="items">{{ el.text }}</span>
<button v-if="showButton(index)">Click me</button>
</div>
</template>
<script setup lang="ts">
//imports
const elements = ref([]);
const addDiv = function() {
elements.value.push({ text: "测试", id: Date.now() })
}
const items = ref();
const showButton = function (index) {
nextTick(() => {
const item = items.value[index] as HTMLElement;
return item.scrollHeight > item.offsetHeight
})
}
</script>
那么有没有办法针对每个元素特定地显示或隐藏我的按钮呢?
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
我使用Vue中的watchers来完成了这个操作,希望能对你有所帮助!
<template> <button @click="addDiv">点击添加div</button> <div v-for="el in elements" :key="el.id" > <span ref="items">{{ el.text }}</span> <button v-if="el.showButton">点击我</button> </div> </template>而且脚本部分,我已经更新了输入部分:
<script setup lang="ts"> //imports import { ref, watch } from 'vue'; const elements = ref<Array<any>>([]); const items = ref<Array<HTMLElement>>([]); const addDiv = function () { elements.value.push({ text: '测试', id: Date.now(), showButton: false }); }; watch(items.value, (newItems) => { console.log('items changed'); let cpt = 0; // you can do it with a for loop too newItems.forEach((item) => { if (item.scrollHeight > item.offsetHeight) { console.log('overflow -> show button'); elements.value[cpt].showButton = true; } cpt++; }); }); </script>