Maison  >  Article  >  interface Web  >  Explication détaillée de la fonction nextTick dans Vue3 : opérations de traitement après la mise à jour du DOM

Explication détaillée de la fonction nextTick dans Vue3 : opérations de traitement après la mise à jour du DOM

WBOY
WBOYoriginal
2023-06-18 09:30:0717602parcourir

Avec le développement rapide de la technologie front-end, des frameworks front-end modernes émergent les uns après les autres, et Vue.js est l'un des meilleurs. Vue.js est un framework JavaScript progressif, facile à apprendre, efficace et flexible, ce qui le rend idéal pour créer des interfaces Web interactives. Vue.js 3 est la dernière version de Vue.js. Elle améliore encore la supériorité de Vue.js grâce à une série d'améliorations continues des performances, une reconstruction architecturale et une expérience de développement améliorée. Parmi elles, la fonction nextTick est une fonctionnalité de Vue.js 3 qui mérite une exploration plus approfondie.

Cet article vous présentera en détail la fonction nextTick dans Vue.js 3, y compris son utilisation de base, ses principes de mise en œuvre et ses scénarios d'application.

1. Utilisation de base de la fonction nextTick

La fonction nextTick dans Vue.js est une méthode asynchrone utilisée pour effectuer certaines opérations spécifiques après la mise à jour du DOM. Elle est exécutée de manière micro-tâche, c'est-à-dire que dans la même boucle d'événements, toutes les tâches de synchronisation sont exécutées immédiatement après leur achèvement. Cela garantira que le rappel appelé par nextTick est exécuté après la mise à jour réelle du DOM, ce qui est très important si nous opérons après la mise à jour du DOM.

Dans Vue.js 3, les fonctions suivantes peuvent être réalisées en utilisant la fonction nextTick :

  1. Exploiter le DOM immédiatement après la modification des données

Étant donné que Vue.js adopte une stratégie de mise à jour asynchrone, le DOM ne changera pas une fois les données modifiées, mettez à jour immédiatement, mais attendez la prochaine mise à jour de Vue.js pour effectuer un nouveau rendu. Si nous devons faire fonctionner le DOM immédiatement après la modification des données, nous pouvons utiliser la fonction nextTick.

Par exemple, nous utilisons l'instruction v-if dans le modèle pour obtenir un effet d'affichage/masquage du contenu. Lorsque nous devons modifier le style DOM en fonction des modifications des données, nous pouvons utiliser la fonction nextTick pour y parvenir.

<template> 
  <div>
    <button @click="toggleContent">切换内容显示</button>
    <div v-if="showContent" ref="content">这是要显示的内容</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      showContent: false
    }
  },
  methods: {
    toggleContent() {
      this.showContent = !this.showContent
      this.$nextTick(() => {
        // 在DOM更新后,修改样式
        this.$refs.content.style.color = 'red'
      })
    }
  }
}
</script>
  1. Obtenir les informations DOM mises à jour

Lorsque les données sont mises à jour et que nous avons besoin d'obtenir les informations DOM mises à jour, nous pouvons utiliser la fonction nextTick. Étant donné que la fonction nextTick sera exécutée après la mise à jour du vrai DOM, nous pouvons obtenir les informations DOM mises à jour.

Par exemple, nous utilisons l'instruction v-for dans le modèle pour parcourir un tableau, puis obtenons les informations de style de l'élément li après la mise à jour du DOM.

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item">{{ item }}</li>
    </ul>
    <button @click="getListStyle">获取列表样式</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: ['item1', 'item2', 'item3']
    }
  },
  methods: {
    getListStyle() {
      this.list.push('item4')
      this.$nextTick(() => {
        // 获取更新后的li元素样式信息
        const liList = document.querySelectorAll('li')
        liList.forEach((li) => {
          console.log(li.style)
        })
      })
    }
  }
}
</script>

2. Principe d'implémentation de la fonction nextTick

Dans Vue.js 3, il existe deux manières principales d'implémenter la fonction nextTick : en utilisant Promise et en utilisant MutationObserver.

  1. Utilisez Promise

Dans Vue.js 3, utilisez Promise pour encapsuler la fonction nextTick. Le processus spécifique est le suivant :

// 初始化Promise
const promise = Promise.resolve()

export function nextTick(callback?: Function) {
  // 将回调包装成一个微任务函数
  return promise.then(callback)
}

Dans le code ci-dessus, Promise.resolve() est utilisé pour initialiser un objet Promise, puis renvoyer un nouvel objet Promise et enregistrer un rappel de fonction de rappel dans la méthode then(). Étant donné que Promise est une microtâche, la fonction de rappel de la fonction nextTick est également une microtâche, qui est plus efficace que setTimeout ou setImmediate.

  1. Utiliser MutationObserver

MutationObserver est une API asynchrone fournie avec le navigateur, qui peut être utilisée pour surveiller les modifications dans l'arborescence DOM afin de réaliser des opérations asynchrones.

Dans Vue.js 3, la fonction nextTick peut être encapsulée via MutationObserver. Le processus spécifique est le suivant :

const callbacks = []
let pending = false

// 回调函数
function flushCallbacks() {
  // 标记异步任务已经在执行
  pending = false
  // 执行回调函数
  const copies = callbacks.slice(0)
  callbacks.length = 0
  for (let i = 0; i < copies.length; i++) {
    copies[i]()
  }
}

// 创建Observer实例
const observer = new MutationObserver(flushCallbacks)

// 注册用户行为
const textNode = document.createTextNode(String(0))
observer.observe(textNode, {
  characterData: true
})

export function nextTick(callback?: Function) {
  callbacks.push(() => {
    if (callback) {
      try {
        callback()
      } catch (e) {
        console.error(e)
      }
    }
  })

  if (!pending) {
    // 标记异步任务未执行
    pending = true
    // 改变textNode的值
    textNode.data = String(Date.now())
  }
}

Dans le code ci-dessus, une instance Observer est créée à l'aide de MutationObserver, puis un nœud textNode est enregistré pour surveiller les modifications de CharacterData. Lorsque l'attribut de données de textNode change, la méthode flushCallbacks() sera. exécuté. Dans nextTick, nous plaçons la fonction de rappel callback dans le tableau callbacks, puis modifions l'attribut data de textNode, déclenchons l'événement de changement CharacterData de MutationObserver, exécutant ainsi la méthode flushCallbacks() et exécutant toutes les fonctions de rappel.

3. Scénarios d'application de la fonction nextTick

La fonction nextTick dans Vue.js propose de nombreux scénarios d'application, et seuls quelques-uns d'entre eux sont présentés ici.

  1. Opération DOM dans l'instruction v-for

Lorsque vous utilisez l'instruction v-for pour parcourir le tableau, si vous devez opérer sur tous les éléments du DOM, vous pouvez utiliser nextTick.

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item">{{ item }}</li>
    </ul>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: ['item1', 'item2', 'item3']
    }
  },
  methods: {
    operateDOM() {
      this.$nextTick(() => {
        // 操作所有的li元素
        const liList = document.querySelectorAll('li')
        liList.forEach((li, index) => {
          li.style.color = `hsl(${index * 50}, 70%, 50%)`
        })
      })
    }
  }
}
</script>

Dans le code, après que l'instruction v-for ait mis à jour le DOM, la fonction nextTick est utilisée pour faire fonctionner tous les éléments li et définir leurs valeurs de couleur.

  1. Opération DOM après mise à jour asynchrone des données

Après la mise à jour asynchrone des données, si vous devez utiliser le DOM mis à jour, vous pouvez également utiliser nextTick.

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="changeMessage">异步更改message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue.js'
    }
  },
  methods: {
    changeMessage() {
      setTimeout(() => {
        this.message = 'Hello World'
        this.$nextTick(() => {
          // 操作更新后的DOM
          document.querySelector('p').style.color = 'red'
        })
      }, 1000)
    }
  }
}
</script>

Dans le code, après avoir mis à jour les données de manière asynchrone, utilisez setTimeout pour retarder 1 seconde, puis mettez à jour la valeur du message. Une fois la valeur du message mise à jour, utilisez la fonction nextTick pour utiliser le DOM mis à jour et définissez la couleur de l'élément p sur rouge.

  1. Ajouter dynamiquement des nœuds DOM

Lors de l'ajout dynamique de nœuds DOM, si vous devez utiliser le nœud DOM nouvellement ajouté, vous pouvez également utiliser nextTick.

<template>
  <div>
    <ul ref="list">
      <li v-for="item in list" :key="item">{{ item }}</li>
    </ul>
    <button @click="addItem">动态添加一项</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      list: ['item1', 'item2', 'item3']
    }
  },
  methods: {
    addItem() {
      this.list.push('item4')
      this.$nextTick(() => {
        // 操作新加入的li元素
        const liList = this.$refs.list.querySelectorAll('li')
        liList[liList.length - 1].style.color = 'red'
      })
    }
  }
}
</script>

Dans le code, l'instruction v-for est utilisée pour parcourir le tableau, puis un élément est ajouté dynamiquement lorsque vous cliquez sur le bouton. Une fois l'ajout terminé, utilisez la fonction nextTick pour faire fonctionner les éléments li nouvellement ajoutés et définir leur couleur sur rouge.

4. Résumé

Dans Vue.js 3, la fonction nextTick est une fonctionnalité très pratique. Elle peut effectuer certaines opérations spécifiques après la mise à jour du DOM, comme modifier le style du DOM, obtenir des informations DOM mises à jour, etc. Il existe deux manières principales d'implémenter la fonction nextTick : en utilisant Promise et en utilisant MutationObserver. Dans le développement réel, selon différents scénarios d'application, nous pouvons utiliser de manière flexible la fonction nextTick pour améliorer l'efficacité du développement et l'expérience utilisateur.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn