Skip to content

Vue 组件怎么通信? ​

父子用 props 向下、事件向上。隔了多层再考虑 provide / inject。没有父子关系、又要共享一份会变的状态时,用 Pinia,而不是全局事件总线。

原理 ​

父组件把数据放进属性,子组件用 defineProps 声明类型和默认值。子组件要改父组件的数据时,发出事件,父组件改自己的状态。不要在子组件里直接改 props。

v-model 是属性和 update:modelValue 事件的约定。一个组件可以有多个 v-model。

provide 可以提供响应式对象。注入方只读,修改仍由提供者负责,否则数据从哪改的会散掉。默认值只在没有提供者时使用。

插槽是父组件把模板交给子组件渲染,适合布局。作用域插槽让子组件把内部数据交回给父组件的模板。见 插槽。

跨页面的「用户信息、购物车」用状态库。事件总线只适合真正的广播,并且要在卸载时关掉。见 发布订阅。

追问 ​

$parent 和 ref 呢?

能用,但父子就焊死了。只在命令式地让子组件聚焦、滚动时用模板 ref。不要用 $parent 去读父组件的数据。

props 太深怎么办?

先看是不是组件拆得过碎。剩下的跨层只读配置用 provide。会频繁改、很多地方写的状态用状态库。

易错点 ​

  • 子组件改 props 对象的字段。对象是引用,父组件的数据会被悄悄改掉。
  • provide 提供了一个普通对象,之后整体替换这个对象,注入方看不到。提供 ref 或 reactive。
  • 用事件总线传递常规表单数据,来源无法追踪。

相关 ​