组合式函数无法直接访问 props,必须由组件显式传参;应优先传递 ref 或 reactive 对象以保持响应性,避免深度解构丢失响应性,类型安全需配合 defineProps 类型声明。

组合式函数本身不参与组件生命周期,也没有内置的 props 上下文,所以不能直接访问父组件传来的 props。必须由组件显式把需要的 prop 值作为参数传进去,这是唯一可靠的方式。
必须手动传参,不能隐式获取
defineProps 只能在 <script setup> 或 setup() 函数中调用,组合式函数(如 useCounter、useTitleFormatter)里调用会报错。它不是组件,没有 this,也不认识 props 对象。
- ✅ 正确做法:在组件中解构或读取 props,再以参数形式传入组合式函数
- ❌ 错误做法:在组合式函数内部写
defineProps、尝试访问全局props、或依赖getCurrentInstance获取上下文
保持响应性:优先传 ref 或 reactive
如果父组件传的是响应式数据(比如 ref 或 reactive 对象),直接把 ref 传进去,组合式函数内部就能自动追踪变化;若传普通值(如字符串、数字字面量),则需配合 computed 或 watch 手动监听。
- 传
ref:函数内可直接用propRef.value,且修改会同步到父组件(注意:仅限父组件允许修改时) - 传
reactive对象:内部可直接读写属性,响应性保留 - 传普通值:建议用
computed(() => props.xxx)包一层,避免值“冻结”
类型安全与解构注意事项
使用 TypeScript + defineProps 声明时,推荐用对象形式并标注类型,这样传入组合式函数的参数也能获得完整类型推导。
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
立即学习“前端免费学习笔记(深入)”;
- 避免在组合式函数内对 props 参数做深度解构(如
const { title } = props),否则会丢失响应性 - 应始终通过
props.title访问,或用toRefs(props)转换后再解构 - 若组合式函数需默认值逻辑,应在组件层处理(用
default配置),而非在函数内硬编码 fallback
典型调用模式示例
父组件中:
<script setup>
import { ref } from 'vue'
import { useFormattedTitle } from './composables/useFormattedTitle'
const title = ref('Hello Vue')
const formatted = useFormattedTitle(title) // 直接传 ref
</script>
组合式函数中:
export function useFormattedTitle(titleRef) {
return computed(() => `【${titleRef.value}】`)
}
这样既清晰又响应,也便于单元测试和复用。

















