Vue组件通信

存在的问题
如果我们一个应用程序将所有的逻辑都放在一个组件中,那么这个组件就会变成非常的臃肿和难以维护
- 组件化的核心思想应该是对组件进行拆分,拆分成一个个小的组件
- 再将这些组件组合嵌套在一起,最终形成我们的应用程序

按照如下的方式进行拆分

各个组件间存在如下关系:
- App 组件是 Header、 Main、 Footer 组件的父组件
- Main 组件是 Banner、 ProductList 组件的父组件
那么这些组件间如何互相通信?
- 比如 App 可能使用了多个 Header,每个地方的 Header 展示的内容不同,那么我们就需要使用者传递给 Header 一些数据,让其进行展示
- 又比如我们在 Main 中一次性请求了 Banner 数据和 ProductList 数据,那么就需要传递给它们来进行展示
- 也可能是子组件中发生了事件,需要由父组件来完成某些操作,那就需要子组件向父组件传递事件
总之,在 Vue 项目中,组件之间的通信是非常重要且常见的
父子通信-父传子
- 父组件传递给子组件: 通过 props 属性
- 子组件传递给父组件: 通过 $emit 触发事件

Props
- Props 是你可以在组件上注册一些自定义的 attribute
- 父组件给这些 attribute 赋值,子组件通过 attribute 的名称获取到对应的值
常见的用法:
- 方式一:字符串数组,数组中的字符串就是 attribute 的名称

- 方式二:对象类型,对象类型我们可以在指定 attribute 名称的同时,指定它需要传递的类型、是否是必须的、默认值等等
export default { |
type 的类型
- String
- Number
- Boolean
- Array
- Object
- Date
- Function
- Symbol
对象类型的其他写法

Prop 的大小写命名
- HTML 中的 attribute 名是大小写不敏感的,所以浏览器会把所有大写字符解释为小写字符
- 当使用 DOM 中的模板时, camelCase (驼峰命名法) 的 prop 名需要使用其等价的 kebab-case (短横线分隔命名) 命名
<div> |
非 Prop 的 Attribute
- 传递给一个组件某个属性,但是该属性并没有定义对应的 props 或者 emits 时,就称之为非 Prop 的 Attribute
- 常见的包括 class、 style、 id 属性等
- 当组件有单个根节点时,非 Prop 的 Attribute 将自动添加到根节点的 Attribute中

禁用 Attribute 继承和多根节点
- 不希望组件的根元素继承 attribute,可以在组件中设置 inheritAttrs: false
- 禁用 attribute 继承的常见情况是需要将 attribute 应用于根元素之外的其他元素
- 我们可以通过 $attrs 来访问所有的非 props 的 attribute
<div> |
- 多个根节点的 attribute 如果没有显示的绑定,那么会报警告,我们必须手动的指定要绑定到哪一个属性上
<template> |
父子通信-子传父
当子组件有一些事件发生的时候,比如在组件中发生了点击,父组件需要切换内容
子组件有一些内容想要传递给父组件的时候
操作:
- 首先,我们需要在子组件中定义好在某些情况下触发的事件名称
- 其次,在父组件中以 v-on 的方式传入要监听的事件名称,并且绑定到对应的方法中
- 最后,在子组件中发生某个事件的时候,根据事件名称触发对应的事件
代码演示:
子组件:
<template> |
父组件:
<template> |
非父子组件通信
除了父子组件之间的通信之外,还会有非父子组件之间的通信, 有两种方式:
- 全局事件总线
- Provide/Inject
当然, 更常见的是使用 Vuex 或 Pinia 状态管理库
全局事件总线 mitt 库
Vue3 从实例中移除了 $on、 $off 和 $once 方法,所以我们如果希望继续使用全局事件总线,要通过第三方的库
- Vue3 官方有推荐一些库,例如 mitt 或 tiny-emitter
- 以 hy-event-store 为例
安装:
npm install hy-event-bus |
封装一个工具 eventbus.js
import { HYEventBus } from 'hy-event-store' |
使用
- 在 App. vue 中监听事件
- 在 Banner. vue 中触发事件

取消之前注册的函数监听
cancelListener() { |
Provide 和 Inject
用于非父子组件之间共享数据
- 比如有一些深度嵌套的组件,子组件想要获取父组件的部分内容
- 仍然将 props 沿着组件链逐级传递会很麻烦
可以使用 Provide 和 Inject
- 无论层级结构有多深,父组件都可以作为其所有子组件的依赖提供者
- 父组件有一个 provide 选项来提供数据
- 子组件有一个 inject 选项来开始使用这些数据

使用
评论
匿名评论
✅ 你无需删除空行,直接评论以获取最佳展示效果