你的浏览器无法正常显示内容,请更换或升级浏览器!

Vue3 组件通信方式全景梳理与选型建议

tenfei
tenfei
发布于2026-08-15 11:52 阅读10次
Vue3 组件通信方式全景梳理与选型建议
系统梳理 Vue3 中所有组件通信方式:props/emit、provide/inject、defineExpose、Pinia 状态管理、事件总线等,分析各自适用场景和避坑点,帮助开发者根据场景选择最合适的通信方案。
# Vue3 组件通信方式全景梳理与选型建议 ## 前言 组件通信是 Vue 开发的基本功,但很多开发者对不同方式的使用场景把握不准,导致代码里 props 满天飞、provide 滥用。本文系统梳理 Vue3 的组件通信方式,给出选型建议。 ## 一、父传子:props 最基础的方式,单向数据流。 ```javascript // 父组件 <ChildComponent :title="title" :count="count" /> // 子组件 const props = defineProps({ title: { type: String, required: true }, count: { type: Number, default: 0 }, }); ``` 注意:不要直接修改 props,如果需要改变,应该用 emit 通知父组件改。 ## 二、子传父:emit ```javascript // 子组件 const emit = defineEmits(["update", "delete"]); emit("update", newValue); // 父组件 <ChildComponent @update="handleUpdate" /> ``` ### v-model 语法糖 ```javascript // 子组件用 defineModel (Vue 3.4+) const model = defineModel(); model.value = newVal; // 自动 emit update:modelValue // 父组件直接 v-model <ChildComponent v-model="inputValue" /> ``` ## 三、跨层级:provide/inject 祖孙组件通信,避免层层透传 props。 ```javascript // 祖先组件 provide("theme", "dark"); provide("userInfo", readonly(userInfo)); // 传只读 // 后代组件 const theme = inject("theme"); const userInfo = inject("userInfo"); ``` 避坑:provide 的对象最好用 readonly 包裹,防止后代随意修改。 ## 四、父访问子:defineExpose ```javascript // 子组件暴露方法 defineExpose({ reset() { form.value = initialForm; }, }); // 父组件用 ref 调用 const childRef = ref(); childRef.value.reset(); ``` 注意:setup 默认是关闭的,必须显式 defineExpose 才能访问。 ## 五、全局状态:Pinia 跨组件共享复杂状态的首选。 ```javascript // stores/cart.ts export const useCartStore = defineStore("cart", () => { const items = ref([]); const total = computed(() => items.value.reduce((s, i) => s + i.price, 0)); function addItem(item) { items.value.push(item); } return { items, total, addItem }; }); ``` 适用:登录态、购物车、主题、全局配置等需要多处读写的状态。 ## 六、事件总线(不推荐) Vue3 移除了实例上的 $on/$emit,官方不推荐事件总线。如需跨组件事件,用 mitt 库: ```javascript import mitt from "mitt"; const emitter = mitt(); // 发送 emitter.emit("logout"); // 接收 emitter.on("logout", () => {}); ``` 但更建议优先用 Pinia 替代事件总线,状态可追踪、易维护。 ## 选型决策表 | 场景 | 推荐方式 | |------|---------| | 父传子静态数据 | props | | 子通知父 | emit / defineModel | | 祖孙跨层级传值 | provide/inject | | 父调用子方法 | defineExpose | | 全局共享状态 | Pinia | | 兄弟组件通信 | Pinia 或共同父组件 | ## 小结 选型原则:能用 props/emit 解决的就不上全局状态;跨层级用 provide/inject;复杂共享状态交给 Pinia;尽量避免事件总线。清晰的通信方式能让代码可维护性大幅提升。

2

0

文章点评
Copyright © from 2021 by namoer.com
458815@qq.com QQ:458815
蜀ICP备2022020274号-2