组合式函数需保持响应性链路不断开:传ref用computed或toValue解包,传reactive对象直接访问属性,传普通值须用watch或toValue监听更新。

组合式函数接收外部传入的响应式参数,核心在于**保持响应性链路不断开**。传 ref 或 reactive 对象时,内部可直接使用;传普通值(如字符串、数字)则需额外处理,否则无法自动响应更新。
传 ref 类型参数:解包或保持响应式引用
当父组件或调用方传入的是 ref(例如 :count="countRef"),组合式函数内推荐不直接取 .value,而是通过 computed 或 toValue 建立响应式依赖:
- 直接解包(简单场景可用):
const value = props.count?.value,但后续 props.count 变更不会触发更新 - 推荐方式:用
computed(() => props.count?.value),确保响应式追踪 - Vue 3.4+ 可用
toValue(来自@vue/reactivity)统一处理 ref/普通值,自动解包并响应变化
传 reactive 对象:直接访问属性即可
若传入的是 reactive 对象(如 :user="userState"),组合式函数中可直接读写其属性,无需额外包装:
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
-
props.user.name是响应式的,修改会同步到源对象 - 避免对整个
props.user重新赋值(如props.user = {...}),这会切断响应性 - 如需局部响应式副本,可用
toRefs(props.user)拆解后返回
传普通值(字符串、数字等):必须配合 watch 或 toValue
普通值没有响应性,传入后不会随父组件更新而变化。必须显式监听:
立即学习“前端免费学习笔记(深入)”;
- 用
watch(() => props.id, (newVal) => { /* 处理 */ })手动响应变更 - 用
watchEffect+toValue更简洁:watchEffect(() => { const id = toValue(props.id); /* 使用 id */ }) - 不建议在组合式函数内缓存普通值(如
let cachedId = props.id),会导致 stale data
最佳实践小结
命名以 use 开头,参数统一用 toValue 处理,返回值用 ref 或 computed 包裹,确保调用方拿到的仍是响应式数据。副作用记得在 onUnmounted 清理。

















