在 Vue3 中,provide
和 inject
用于实现跨层级组件通信。以下是一个简单的示例:
1. 父组件 (祖先组件) - 提供数据
javascript
复制
// ParentComponent.vue import { provide, ref, reactive } from 'vue'; export default { setup() { // 提供静态数据 provide('message', 'Hello from Parent!'); // 提供响应式数据 const count = ref(0); provide('count', count); // 提供对象和方法 const user = reactive({ name: 'Alice', age: 25 }); const updateUser = () => { user.age++; }; provide('userData', { user, updateUser }); return { count }; } };
2. 子组件 (后代组件) - 注入数据
javascript
复制
// ChildComponent.vue import { inject } from 'vue'; export default { setup() { // 注入基本类型(带默认值) const message = inject('message', 'Default message'); // 注入响应式数据 const count = inject('count'); // 注入对象和方法 const { user, updateUser } = inject('userData'); // 修改响应式数据 const increment = () => { count.value++; }; return { message, count, user, updateUser, increment }; } };
3. 模板使用示例
html
复制
<!-- ChildComponent.vue 模板部分 --> <template> <div> <h3>Child Component</h3> <p>Message: {{ message }}</p> <p>Count: {{ count }}</p> <p>User: {{ user.name }} ({{ user.age }})</p> <button @click="increment">Increment Count</button> <button @click="updateUser">Update User Age</button> </div> </template>
运行 HTML
关键点说明:
响应式数据:使用
ref
/reactive
创建响应式数据,注入后依然保持响应性默认值:
inject('key', defaultValue)
第二个参数为默认值类型支持:可以注入任意类型(基本类型、对象、函数等)
代码组织:推荐使用 Symbol 作为 key 避免命名冲突(适用于大型项目)
符号键示例(可选)
javascript
复制
// keys.js export const MESSAGE_KEY = Symbol('message'); export const COUNT_KEY = Symbol('count'); // 父组件 import { MESSAGE_KEY, COUNT_KEY } from './keys'; provide(MESSAGE_KEY, 'Hello World'); // 子组件 const message = inject(MESSAGE_KEY);
这个模式特别适合以下场景:
主题/样式配置
全局状态管理(简单场景)
多层嵌套组件通信
共享工具函数/实例
注意:对于复杂应用,建议使用 Pinia 进行状态管理,但对于简单的组件层级通信,provide/inject
更加轻量。