Vue3.2 新增指令 v-memo 用法詳解,提高性能的又一利器?。?!

哈嘍,大家好 我是xy???????。不少同學(xué)可能沒有發(fā)現(xiàn), Vue3.2 新增了一個指令 v-memo, 引入這個指令的目的是幫助大家更好的為我們的應(yīng)用做性能優(yōu)化??

v-memo 官方定義
「?? 期望的綁定值類型:」any[]

「?? 詳細(xì)信息」

緩存一個模板的子樹。在元素和組件上都可以使用。為了實現(xiàn)緩存,該指令需要傳入一個固定長度的依賴值數(shù)組進(jìn)行比較。如果數(shù)組里的每個值都與最后一次的渲染相同,那么整個子樹的更新將被跳過。舉例來說:

  <div v-memo="[valueA, valueB]">
    ...
  </div>
當(dāng)組件重新渲染,如果 valueA 和 valueB 都保持不變,這個 <div> 及其子項的所有更新都將被跳過。實際上,甚至虛擬 DOM 的 vnode 創(chuàng)建也將被跳過,因為緩存的子樹副本可以被重新使用。

正確指定緩存數(shù)組很重要,否則應(yīng)該生效的更新可能被跳過。v-memo 傳入空依賴數(shù)組 (v-memo="[]") 將與 v-once 效果相同。

我對 v-memo 的理解
簡單理解:v-memo 接受一個依賴的數(shù)組,依賴的數(shù)組變化,v-memo 所對應(yīng)的 DOM 包括子集將會重新渲染,反過來說,如果依賴的數(shù)組不變,即使整組件重新渲染了,v-memo 所對應(yīng)的 DOM 包括子集更新都將被跳過

另外,依賴的數(shù)組接受一個或多個值 v-memo="[valueOne, valueTwo]",也接受像 v-memo="myValue === true"這樣的表達(dá)式。

如果用一個空數(shù)組調(diào)用 v-memo 相當(dāng)于使用 v-once,只會渲染該部分組件一次。

與 v-for 一起使用
v-memo 僅用于性能至上場景中的微小優(yōu)化,應(yīng)該很少需要。最常見的情況可能是有助于渲染海量 v-for 列表 (長度超過 1000 的情況):

<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
  <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
  <p>...more child nodes</p>
</div>
當(dāng)組件的 selected 狀態(tài)改變,默認(rèn)會重新創(chuàng)建大量的 vnode,盡管絕大部分都跟之前是一模一樣的。v-memo 用在這里本質(zhì)上是在說“只有當(dāng)該項的被選中狀態(tài)改變時才需要更新”。這使得每個選中狀態(tài)沒有變的項能完全重用之前的 vnode 并跳過差異比較。注意這里 memo 依賴數(shù)組中并不需要包含 item.id,因為 Vue 也會根據(jù) item 的 :key 進(jìn)行判斷。






使用場景
假設(shè)后端返回來了 10000 條數(shù)據(jù), 前端需要做篩選, 選出符合條件的數(shù)據(jù)進(jìn)行展示, 如果沒有符合條件的,則保持上次的搜索結(jié)果。

<template>
  <div class="home">
    <input type="text" v-model="value">
    <!-- v-memo中值若不發(fā)生變化,則不會進(jìn)行更新 -->
    <ul v-memo="[shouldUpdate]">
        <li class="licss" v-for="item in arr" :key="item">
          {{ value }} -- {{ animalType[value] }}
        </li>
    </ul>
  </div>
</template>
<script lang="ts" setup>
import { ref } from "@vue/reactivity"
import { watch } from "@vue/runtime-core"
const arr=new Array(10000)
const animalType={
  'mie':'??',
  'mo':'??',
  'miao':'??',
}
const value=ref('mie')
const shouldUpdate=ref(0)
// 監(jiān)聽value(輸入框中的值)。
// 如果數(shù)據(jù)發(fā)生變化,并且在animalType對象中存在。試圖進(jìn)行更新。否則試圖不進(jìn)行更新。
watch(()=>value.value,()=>{
  if(Object.keys(animalType).includes(value.value)){
    shouldUpdate.value++
  }
})
</script>






作者:前端小菜雞之菜雞互啄


歡迎關(guān)注微信公眾號 :前端開發(fā)愛好者


添加好友備注【進(jìn)階學(xué)習(xí)】拉你進(jìn)技術(shù)交流群