I have elements that are rendered using v-for Each element consist of text and button I need to show a button only if text is overflow div's height
<div v-for="el in elements" :key="el.id">
<span>{{ el.text }}</span>
<button>Click me</button>
</div>
Evident solution is use v-if, but what should I based on? I need to calculate height of text and decide to show button or not So I need refs for divs and function to determine show or not:
<template>
<button @click="addDiv"> Click to add 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: "Test", id: Date.now() })
}
const items = ref();
const showButton = function (index) {
const item = items.value[index] as HTMLElement;
return item.scrollHeight > item.offsetHeight
}
</script>
But I found the issue is that items
are not synchronous with DOM. So it is clear why, DOM is updated asynchronously and that's why my data is a little bit late
So I decided to add nextTick()
in my showButton function, but it started to return Promise, which leads to v-if always true
<template>
<button @click="addDiv"> Click to add 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: "Test", id: Date.now() })
}
const items = ref();
const showButton = function (index) {
nextTick(() => {
const item = items.value[index] as HTMLElement;
return item.scrollHeight > item.offsetHeight
})
}
</script>
So is there any way to show or not my button for each element specifically?