customRef 是 Vue 3 中的一个高级响应式 API,用于创建自定义的响应式引用(ref),允许开发者对依赖追踪和更新触发过程进行细粒度控制。它通过一个工厂函数接收 track 和 trigger 两个函数,返回一个包含 get 和 set 方法的对象,从而实现灵活的响应式逻辑。
基本用法
customRef 的核心是自定义依赖管理:
- 工厂函数 :接收
track(用于收集依赖)和trigger(用于触发更新)作为参数。 - 返回对象 :必须包含
get方法(读取值时调用track收集依赖)和set方法(设置值时调用trigger触发更新)。
基础示例:
const customRefValue = customRef((track, trigger) => {
let value = 0;
return {
get: () => {
track(); // 收集依赖
return value;
},
set: (newValue) => {
value = newValue;
trigger(); // 触发更新
}
};
});
主要应用场景
customRef 适用于需要精细控制响应式行为的场景:
-
防抖/节流 :在设置值后延迟触发更新,避免频繁响应。例如,实现输入防抖:
function useDebouncedRef(value, delay) { let timer; return customRef((track, trigger) => ({ get: () => { track(); return value; }, set: (newValue) => { clearTimeout(timer); timer = setTimeout(() => { value = newValue; trigger(); }, delay); } })); } -
与外部状态集成 :如本地存储(localStorage)同步:
function useLocalStorage(key, initialValue) { return customRef((track, trigger) => ({ get: () => { track(); return localStorage.getItem(key) ?? initialValue; }, set: (value) => { localStorage.setItem(key, value); trigger(); } })); } -
性能优化:通过浅层响应式避免不必要的深层转换,适用于大型数据结构。
与 ref 的区别
ref提供基础响应式包装,自动处理深层转换,适合常规场景。customRef允许手动控制依赖追踪和更新时机,更灵活但需谨慎使用,例如避免在 getter 中返回新对象导致不必要的重新渲染。
注意事项
- 依赖管理 :确保在
get中调用track,在set中调用trigger,否则响应式失效。 - 副作用处理 :结合
effectScope等 API 管理副作用生命周期,避免内存泄漏。
通过 customRef,开发者可以构建高度定制化的响应式逻辑,提升应用性能或实现复杂交互。