Le titre réexprimé est : v-if basé sur les mises à jour du DOM
P粉163951336
P粉163951336 2023-09-10 08:59:42
0
1
529

J'ai rendu certains éléments en utilisant v-for Chaque élément contient du texte et des boutons Je dois afficher le bouton uniquement lorsque le texte dépasse la hauteur du div

<div v-for="el in elements" :key="el.id">
    <span>{{ el.text }}</span>
    <button>Click me</button>
</div>

La solution évidente est d'utiliser v-if, mais sur quelle base dois-je baser cela ? Je dois calculer la hauteur du texte et décider d'afficher ou non le bouton Par conséquent, je dois utiliser des références pour référencer les divs et une fonction pour déterminer s'il faut afficher :

<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>

Mais j'ai trouvé que le problème n'est itemspas synchronisé avec le DOM. Alors évidemment, le DOM est mis à jour de manière asynchrone et c'est pour ça que mes données arrivent un peu en retard J'ai donc décidé d'ajouter nextTick() dans ma fonction showButton, mais elle a commencé à renvoyer Promise, ce qui a fait que le v-if était toujours vrai

<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>

Alors, existe-t-il un moyen d'afficher ou de masquer mes boutons spécifiquement pour chaque élément ?

P粉163951336
P粉163951336

répondre à tous(1)
P粉187677012

J'ai utilisé watchers dans Vue pour réaliser cette opération, j'espère que cela pourra vous être utile !

<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>

Et la partie script, j'ai mis à jour la partie saisie :

<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>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal