Vue3.2 新增 v-memo

4,325 阅读2分钟

image.png

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第7天,点击查看活动详情

这个指令是Vue3.2新增的内置指令,大致的作用就是小幅度手动提升一部分性能

官网文档 cn.vuejs.org/api/built-i…

用法

在组件和元素都可以使用,主要是可以缓存 期望的类型是个数组any[],该指令需要传入一个固定长度的依赖值数组进行比较。如果数组里的每个值都与最后一次的渲染相同,那么他的更新将会被跳过,甚至虚拟 DOM 的 vnode 创建也将被跳过,提升了性能。

tips:如果v-memo="[]" 传入的是一个空数组,那么他的效果和v-once 一样

<div v-memo="[val]"></div>

配合v-for

配合v-for 属于最常见的情况,但是只有助于大数据量的情况例如(1000条以上)

tips: 当搭配 v-for 使用 v-memo,确保两者都绑定在同一个元素上。v-memo 不能用在 v-for 内部。

测试代码 未加v-memo 一万条数据

当组件的 selected 状态改变,默认会重新创建大量的 vnode,尽管绝大部分都跟之前是一模一样的。v-memo 用在这里本质上是在说“只有当该项的被选中状态改变时才需要更新”。这使得每个选中状态没有变的项能完全重用之前的 vnode 并跳过差异比较。

<template>
  <div>
    <div @click="select(item.id)"   :key="item.id" v-for="(item) in arr">
      {{ item.id }} - selected: {{ item.id == active }}
    </div>
  </div>
</template>

<script setup lang='ts'>
import { ref, reactive } from 'vue'

const arr = reactive<any[]>([])
for (let i = 0; i < 10000; i++) {
  arr.push({
    id: i + 1,
    name: "test"
  })
}

const active = ref(1)

const select = async (index: number) => {
  active.value = index;
  console.time()
  await Promise.resolve()
  console.timeEnd()
}

</script>

<style scoped lang='less'>

</style>

image.png

添加v-memo 之后 能缩短小部分时间

image.png

总结

如果你的项目对性能要求非常严格可以使用,但也只是小部分提升性能,如果你的项目平时没有那么大的数据量,感觉没什么有用。