v-once

仅渲染元素和组件一次,并跳过之后的更新。

在随后的重新渲染,元素/组件及其所有子项将被当作静态内容并跳过渲染。这可以用来优化更新时的性能。

<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>

<!-- 带有子元素的元素 -->
<div v-once>
<h1>Comment</h1>
<p>{{msg}}</p>
</div>

<!-- 组件 -->
<my-component v-once :comment="msg" />

<!-- v-for 指令 -->
<ul>
<li v-for="i in list" v-once>{{i}}</li>
</ul>

v-memo

缓存一个模板的子树。在元素和组件上都可以使用。为了实现缓存,该指令需要传入一个固定长度的依赖值数组进行比较。如果数组里的每个值都与最后一次的渲染相同,那么整个子树的更新将被跳过。

<div v-memo="[valueA, valueB]">
...
</div>

当组件重新渲染,如果valueAvalueB都保持不变,这个<div>及其子项的所有更新都将被跳过。实际上,甚至虚拟DOM的vnode创建也将被跳过,因为缓存的子树副本可以被重新使用。

正确指定缓存数组很重要,否则应该生效的更新可能被跳过。v-memo传入空依赖数组v-memo="[]"将与v-once效果相同。

v-for一起使用,有助于渲染海量数据列表:

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

当组件的selected状态改变,默认会重新创建大量的vnode,尽管绝大部分都跟之前时一模一样的。v-memo用在这里,只要选中状态没有变化的项能够完全重用之前的vnode并跳过差异比较。

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