概要
从 Vue 3.2 开始添加了v-memo
指令,v-memo
指令可以通过省略不必要的重新渲染来提高性能。
v-memo
如果指定的所有值都与上次渲染的结果相同,该指令将跳过重新渲染整个子树。
如何使用v-memo 指令
如下图,重新渲染组件时,如果数组中指定的valueA
和valueB
与上次渲染的值相同,则跳过div
下元素的重新渲染。
<div v-memo="[valueA, valueB]">
如果值未更改,就不重新渲染
</div>
测试一下
我们可以创建 两个组件ChildA.vue
和 ChildB.vue
并在onUpdated()
的时候打印日志。
-
ChildA.vue
// src/components/ChildA.vue
<script setup lang="ts">
import {onUpdated} from "vue";
const props = defineProps({
msg:{
type:String,
default:'ChildA组件'
}
})
onUpdated(()=>{
console.log('ChildA.vue重新渲染')
})
</script>
<template>
<div class="child-a">ChildA: {{ msg }}</div>
</template>
-
ChildB.vue
// src/components/ChildB.vue
<script setup lang="ts">
import {onUpdated} from "vue";
const props = defineProps({
msg:{
type:String,
default:'ChildB组件'
}
})
onUpdated(()=>{
console.log('ChildB.vue重新渲染')
})
</script>
<template>
<div class="child-a">ChildB: {{ msg }}</div>
</template>
-
使用子组件
以下代码我们可以定义两个参数msg
和dummy
,然后我们有两个按钮:一个用来清除msg
的值,另一个用来递增dummy
的值。
<template>
<child-a :msg="msg" />
<child-b v-memo="[dummy]" :msg="msg"/>
<p>重新渲染: {{ dummy }}</p>
<v-btn @click="clearMsg">清除msg</v-btn>
<v-btn @click="countUp">计数</v-btn>
</template>
<script lang="ts" setup>
import ChildA from "../components/ChildA.vue";
import ChildB from "../components/ChildB.vue";
import {ref} from "vue";
const msg = ref('传入的消息')
const clearMsg = () => {
msg.value = ''
}
const dummy = ref(0);
const countUp = () => {
dummy.value++;
};
</script>
当msg
正常更新时,props
中接收msg
的两个组件被重新渲染,但是ChildB
是由v-memo
指定的,如果dummy
改变了就会重新渲染。
所以当我们执行clearMsg
事件时只有ChildA
会被重新渲染,只有当我们执行countUp
事件时ChildB
次会被重新渲染。
v-memo=”[]”效果等同于v-once
此外,如果为 v-memo 值指定的数组为空,则该函数将与 v-once 相同。如下面例子:
<div v-memo="[]">
与 v-once 相同(第一次渲染后不重新渲染)
</div>
与 v-for 一起使用
v-memo
仅用于性能至上场景中的微小优化,应该很少需要。最常见的情况可能是有助于渲染海量 v-for
列表 (长度超过 1000 的情况),我们可以看一下下面的代码:
这是显示 10 个列表并通过单击按钮更改所选列表
<template>
<v-btn @click="reselectItemId">更改选定的ID</v-btn>
<ul
v-for="itemId in itemIdList"
:key="itemId"
v-memo="[itemId === selectedItemId]"
>
<li>
ID: {{ itemId }}, 选择:
{{ itemId === selectedItemId ? "← 选择" : "" }}
</li>
</ul>
</template>
<script lang="ts" setup>
import {reactive, ref} from "vue";
const maxItem = 10;
const itemIdList = reactive([]);
for (let i = 0; i < maxItem; i++) {
itemIdList.push(i);
}
const selectedItemId = ref(0);
const reselectItemId = () => {
const rand = Math.floor(Math.random() * maxItem);
selectedItemId.value = rand;
};
</script>
当执行reselectItemId
事件时,只会更新之前选择的列表和新选择的列表,其余元素不会更新。
这次是10个列表作为示例,但如果数量更大,例如1000或10,000个列表,则可以提高性能。
以上就是今日分享的文章,希望小伙伴们都能get到新知识,晚安咯!
原文始发于微信公众号(大前端编程教学):Vue3使用 v-memo 指令优化渲染
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/224124.html