I have some elements rendered using v-for Each element contains text and buttons I need to show the button only when the text overflows the height of the div
<div v-for="el in elements" :key="el.id"> <span>{{ el.text }}</span> <button>Click me</button> </div>
The obvious solution is to use v-if, but on what basis should I base my judgment? I need to calculate the height of the text and decide whether to show the button or not Therefore, I need to use refs to reference the divs and a function to determine whether to display:
<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>
But I found that the problem is that items
is out of sync with the DOM. So obviously, the DOM is updated asynchronously and that's why my data is a bit late
So I decided to add nextTick()
in my showButton function, but it started returning Promise which caused the v-if to always be 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>
So is there a way to show or hide my buttons specifically for each element?
I used watchers in Vue to complete this operation. I hope it can be helpful to you!
And the script part, I have updated the input part: