vue 3 组件间数据共享应按关系层级选择方案:父子用 props/emits;跨层级用 provide/inject;非父子用自定义 composable;大型应用用 pinia。

Vue 3 的 Composition API 提供了多种自然、轻量又语义清晰的方式实现组件间数据共享,关键在于根据关系层级和共享范围选择合适方案——不是“只用一种”,而是按需组合使用。
父子组件:优先用 props + emits
这是最直接、最可控的数据流方式。父组件通过 props 向子组件传值,子组件通过 emits 触发事件通知父组件更新。适合结构明确、通信频繁的场景。
- props 是单向的,确保数据流向清晰,避免隐式副作用
- 子组件中用
defineEmits声明事件,配合v-model语法糖可自动映射为modelValue和update:modelValue,简化双向绑定逻辑 - 不建议在每个子组件里重复调用同一 composable(如
useInput())来管理状态——这会创建多个独立响应式引用,破坏数据一致性
跨层级嵌套:用 provide / inject
当数据需要穿透多层组件(比如从根组件传到孙子甚至曾孙组件),避免逐级透传 props,provide / inject 是理想选择。
- 只能在
setup()或<script setup></script>中使用,且必须成对出现 -
provide接收一个 key 和响应式数据(推荐用ref或reactive包裹,保证响应性) -
inject在任意后代组件中获取该数据,返回的是原始响应式引用,修改会同步影响所有注入处 - 注意:inject 返回值可能为 undefined,建议提供默认值或用
inject(key, defaultValue)
非父子/全局轻量共享:自定义 Composable
对于小型项目或局部功能模块(如用户登录态、主题色、表单校验规则),无需引入 Pinia 或 Vuex,可封装一个响应式状态模块。
- 在单独的 JS 文件中用
ref或reactive定义状态,再通过函数导出读写方法 - 多个组件导入同一 composable,拿到的是同一个响应式对象的引用,天然支持跨组件响应更新
- 适合组合逻辑+状态+副作用(如 localStorage 同步、watch 监听)于一体,比单纯共享数据更内聚
- 注意避免意外解构
reactive对象导致响应性丢失,需要用toRefs处理
复杂状态或大型应用:搭配 Pinia
当共享数据涉及异步操作、持久化、模块拆分、调试追踪等需求时,Pinia 是 Vue 3 官方推荐的状态库,与 Composition API 高度契合。
- store 定义简洁,支持 TypeScript、Devtools、服务端渲染等开箱即用能力
- 每个 store 是独立的响应式对象,可通过
useXXXStore()在任意组件中调用 - 相比 Vuex,API 更扁平,学习成本低,且无 mutation 类型约束负担
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










