Vue3兄弟,爷孙组件间传值【包含手撸发布/订阅类】

news/2024/11/24 7:16:15/

Vue2【Vue基础十】— 兄弟组件之间传值【中央事件总线,消息订阅与发布】
Vue2 : 【Vue基础九】–父子组件传值

一、 兄弟组件

1-1 事件总线

  • 使用Vue3,会发现,原本得心应手的eventBus突然不灵了
  • Vue3不再提供$on与emit函数,Vue实例不再实现事件接口。官方推荐引入外部工具实现,或者自己手撸一个事件类

1-1-1 使用EventBus

  1. 引入/编写事件库
  2. 在入口文件中挂载
  3. 在组件中引入并使用

1-1-2 不借助插件的原生使用方式

  1. 引入/编写事件库

    • 方法一: 引入官方推荐的mitt
    • 方法二: 手撸一个简单的发布/订阅类
      // eventBus.js
      export default class EventBus{constructor(){this.events = {};}emit(eventName, data) {if (this.events[eventName]) {this.events[eventName].forEach(function(fn) {fn(data);});}}on(eventName, fn) {this.events[eventName] = this.events[eventName] || [];this.events[eventName].push(fn);}off(eventName, fn) {if (this.events[eventName]) {for (var i = 0; i < this.events[eventName].length; i++) {if (this.events[eventName][i] === fn) {this.events[eventName].splice(i, 1);break;}};}}
      }
      
  2. 在入口文件main.js中执行挂载

// main.js
import { createApp } from 'vue'
import App from './App.vue'
// ① 引入事件类
// 自己编写的或者mitt皆可
import EventBus from 'lib/bus.js'
// 或者:import EventBus from 'mitt'
const $bus = new EventBus()// ② 挂载
// 1.使用provide提供
app.provide('$bus', $bus)
// 2.挂载到this上
app.config.globalProperties.$bus = $bus
  1. 在组件中引入并使用
    • 在creates中使用
    // Button.vue
    export default {created() {this.$bus.emit('ButtonCreated')}
    }
    
    • 在setup中使用

    注意: 因为在setup中无法访问到应用实例(this),如果你需要在setup中使用eventBus,则需要通过provide/inject方式引入

    // Button.vue
    import { inject } from 'vue'
    export default {setup() {const $bus = inject('$bus')$bus.emit('ButtonSetup')}
    }
    

二、 爷孙组件

2-1 props和$emit

最常用的父子组件通信方式,爷爷–> 父 ----> 子

1、 父组件向子组件传递数据是通过prop传递的,子组件传递数据给父组件是通过$emit触发事件做到的
2、 处理父子组件之间的数据传输有一个问题:

  • 多层嵌套,父组件A下面有子组件B,组件B下面有组件C,A想传递给C怎么办?
  • 采用第一种方法,必须让组件A通过prop传递消息给组件B,组件B再传给C
  • Vue2.4之后,引入了attrs和listeners来解决这个问题

2-2 attrs和listeners

1、 attrs和listeners的过程:

父组件A下面有子组件B,组件B下面有组件C,组件A传递数据给组件B

  • C组件
Vue.component('C', {template: `<div> <input type="text" v-model="$attrs.messageC" @input="passCData($attrs.messageC)"> </div>`,methods: {passCData(val) {// 触发父组件A中的事件this.$emit('getCData',val)}}
})
  • B组件
Vue.component('B', {data() {return {myMessage: this.message}},template: `<div> <input type="text" v-model="myMessage" @input="passData(myMessage)"> <C v-bind="$attrs" v-on="$listeners"></C> </div> 	`// 得到父组件传递过来的数据props: ['message'],methods: {passData(val) {// 触发父组件中的事件this.$emit('getChildData',val)}}
})
  • A组件
Vue.component('A',{template: `<div> <p>this is parent compoent!</p> <B  :messageC="messageC"  :message="message"  v-on:getCData="getCData"  v-on:getChildData="getChildData(message)"> </B> </div> `,data() {return {message: 'Hello',messageC: 'Hello c'}},methods: {getChildData(val) {console.log('这是来自B组件的数据')},// 执行C子组件触发的事件getCData(val) {console.log("这是来自C组建的数据:"+val)}}
})
var app = new Vue({el: '#app',template: `<div><A></A></div>`
})

2、 解析:

  • C组件中能直接触发getData的原因: B组件调用C组件时,使用v-on绑定了$listeners属性
  • 通过v-bind绑定$attrs属性,C组件可以直接获取到A组件中传递下来的props(除了B组件中props声明的)

三、 v-model

1、 父组件通过v-model传递值给子组件时,会自动传递一个value的prop属性,在子组件中通过this.$emit(‘input’,val)自动修改v-model绑定的值

后续回来得看看

  • https://blog.csdn.net/m0_56986233/article/details/121405388
  • https://www.zhihu.com/question/466846675

http://www.ppmy.cn/news/10868.html

相关文章

Pytorch - 使用pytorch自带的Resnet作为网络的backbone

在使用Pytorch搭建自己的神经网络框架时&#xff0c;经常需要使用Pytorch中内置的torchvision.models中的模型作为特征提取的Backbone&#xff0c;然后再在这个基础上进行更加复杂的网络搭建。 在这里以使用Pytorch中内置的Resnet18为例&#xff0c;如何作为Backbone层进行使用…

环形缓冲区

文章目录一. 什么是环形缓冲区&#xff1f;二、实现环形缓冲区&#xff1a;三、环形缓冲区示例代码&#xff1a;总结一. 什么是环形缓冲区&#xff1f; 环形缓冲区 是一段 先进先出 的循环缓冲区&#xff0c;有一定的大小&#xff0c;我们可以把它抽象理解为一块环形的内存。 …

2023年底,我要通过这5点,实现博客访问量500W

说实话&#xff0c;这真的是一个非常高远的flag&#xff0c;因为我目前只有35W&#xff0c;但根据我2个月前还是12W的访问量&#xff0c;我觉得我还是可以拼一把的&#xff0c;在这里我想向大家分享一下我的计划&#xff0c;如何达成2023年底&#xff0c;博客访问量达到500W的K…

java 微服务之docker基础入门 docker部署 镜像相关命令 容器命令 数据卷 DockerCompose Docker镜像仓库

初识Docker 项目部署的问题 什么是Docker 不同环境的操作系统不同&#xff0c;Docker如何解决&#xff1f;我们先来了解下操作系统结构 Docker与虚拟机 虚拟机是在一个系统内&#xff0c;运行另外一个系统 镜像和容器 镜像&#xff08;Image&#xff09;&#xff1a;Docker将…

通讯电平转换电路中的经典设计

今天给大家分享几个通讯电平转换电路。 有初学者问&#xff1a;什么是电平转换&#xff1f;举个例子&#xff0c;比如下面这个电路&#xff1a; 单片机的工作电压是5V&#xff0c;蓝牙模块的工作电压是3.3V&#xff0c;两者之间要进行通讯&#xff0c;TXD和RXD引脚就要进行连接…

ClickHouse 挺快,esProc SPL 更快

开源分析数据库ClickHouse以快著称&#xff0c;真的如此吗&#xff1f;我们通过对比测试来验证一下。 ClickHouse vs Oracle 先用ClickHouse&#xff08;简称CH&#xff09;、Oracle数据库&#xff08;简称ORA&#xff09;一起在相同的软硬件环境下做对比测试。测试基准使用国…

Spring Boot 3.0横空出世,快来看看是不是该升级了

文章目录简介对JAVA17和JAVA19的支持recordText BlocksSwitch Expressionsinstanceof模式匹配Sealed Classes and Interfaces迁移到Jakarta EEGraalVM Native Image Support对Micrometer的支持其他的一些改动简介 Spring boot 3.0于2022年11月正式发布了&#xff0c;这次的发布…

设计模式之职责链模式

设计模式之职责链模式 1&#xff09;职责链模式&#xff08;Chain Of Responsibility Pattern&#xff09;&#xff0c;又叫责任链模式&#xff0c;为请求创建了一个接受者对象的链。这种模式对请求的发送者和接收者进行解耦。 2&#xff09;职责链模式通常每个接收者都包含另…