vue3中shallowRef有什么作用?

46 阅读2分钟

在 Vue3 里,shallowRef是一个很实用的函数,其作用是创建一种特殊的 ref 对象,它只对自身的值变化进行追踪,而不会递归追踪内部属性的变化。下面详细介绍它的功能和适用情形。

主要功能

  • 浅层响应性shallowRef仅对.value的赋值操作作出响应,而内部对象的属性变化不会触发更新。
  • 性能优化:在处理大型数据结构或者第三方对象(像 DOM 元素、API 响应数据)时,若无需追踪内部变化,使用它能避免不必要的响应式开销。
  • 保持原始对象:它不会像ref那样对深层对象进行代理转换,有助于维持对象的原始状态。

典型应用场景

  1. 缓存大型数据
    当你有大量静态数据,且不需要监听其变化时,可以使用shallowRef来避免性能浪费。
const largeData = shallowRef(getLargeDataFromAPI()); // 数据更新时才需手动触发更新
  1. 集成第三方库
    在集成第三方库时,使用shallowRef可以存储库返回的实例,防止 Vue 对其进行不必要的代理。
const map = shallowRef(null);

onMounted(() => {
  map.value = new MapLibreGL.Map(...); // 存储原生DOM或库实例
});
  1. 手动控制更新
    如果你希望手动控制更新时机,以减少渲染次数,shallowRef是个不错的选择。
const state = shallowRef({ count: 0 });

function increment() {
  state.value.count++; // 不会触发更新
  nextTick(() => {
    forceUpdate(); // 手动触发更新
  });
}

与普通 ref 的差异

特性refshallowRef
深层响应性具备不具备
对象代理进行代理转换保持原始对象
触发更新的方式对象属性变化会触发更新.value赋值操作会触发更新

手动触发更新的方法

如果使用了shallowRef,但又需要在内部属性变化时触发更新,可以采用以下方法:

// 方法一:替换整个value
state.value = { ...state.value, count: state.value.count + 1 };

// 方法二:结合triggerRef强制更新
import { shallowRef, triggerRef } from 'vue';

const state = shallowRef({ count: 0 });

function increment() {
  state.value.count++;
  triggerRef(state); // 手动触发更新
}

使用建议

  • 当你需要处理大型数据结构,并且不需要追踪内部变化时,优先考虑使用shallowRef

  • 存储第三方实例(如 DOM、Canvas、Map 等)时,shallowRef是很好的选择。

  • 如果需要响应式地追踪内部变化,应使用普通的refreactive

通过合理运用shallowRef,可以在 Vue 应用中实现更精准的响应式控制,从而优化性能。