vue3学习记录-组件通信

news2024/11/25 12:24:56

vue3学习记录-组件通信

  • 1.父子组件通信
  • 2.兄弟组件传值
    • 2.1 以父组件为媒介
    • 2.2 发布订阅模式
    • 2.3 使用mitt
      • 2.3.1 全局使用
      • 2.3.2 局部使用

1.父子组件通信

父组件:

<template>
  父组件原有的title:{{ title }}
  <p>---</p>
  <com :title="title" :flag="true" @changeTitle="changeTitle"></com>
</template>

<script setup>
import { computed, ref } from 'vue'
import com from './components/com.vue'
let title = ref('我是标题')
function changeTitle(newTitle){
  title.value = newTitle
}
</script>

<style></style>

子组件:

<template>
    <div>
        我是子组件
        <p>子组件的title:{{ title }}</p>
        <button @click="changeTitle1">我要给父组件传参</button>
    </div>
</template>

<script setup>
defineProps({
    title: {
        default: '',
        type: String
    },
    flag: Boolean
})
const emit1 = defineEmits(['changeTitle'])
function changeTitle1() {
    emit1('changeTitle', '我是子组件传给父组件的参数')
}

//子传父事件 
//1.const emit1 = defineEmits(['changeTitle'])定义emit
//2.直接在事件后 emit1('changeTitle', '我是子组件传给父组件的参数'),然后父组件接收

</script>

<style lang="scss" scoped></style>

defineProps父传子定义,defineEmits子传父定义

2.兄弟组件传值

2.1 以父组件为媒介

//App.vue
<script setup>
import A from './components/A.vue';
import B from './components/B.vue';
import { ref } from 'vue';
const mainFlag = ref(false)
const clickEvent1 = (val) => {
  mainFlag.value = val
  console.log('clickEvent', val);
};
</script>


<template>
  <A @clickEvent="clickEvent1"></A>
  <B :mainFlag="mainFlag"></B>
</template>

<style scoped></style>

//A.vue
<template>
  <div class="container">
    <p>我是A组件
    </p>
    <el-button @click="clickEvent1">分发事件</el-button>
  </div>
  </template>
  
  <script setup>
  import { ref, reactive} from 'vue'
  const flag = ref(false)
  const clickEvent1 = () =>{
    flag.value =!flag.value
    emit1('clickEvent',flag.value)
  }
  const emit1 = defineEmits(['clickEvent'])
  </script>
  <style lang='scss' scoped>
  .container{
      width: 200px;
      height: 200px;
      background-color: lightcoral;
      margin-bottom: 10px;
  }
  </style>
//B.vue
<template>
  <div class="container">
      <p>我是B组件</p>
      {{ mainFlag }}
  </div>
</template>

<script setup>
import { ref, reactive } from 'vue'
defineProps({
  mainFlag: {
      type: Boolean,
      required: true
  }
})

</script>
<style lang='scss' scoped>
.container {
  width: 200px;
  height: 200px;
  background-color: lightblue;
}
</style>

A组件分发事件给父组件,父组件再把值传给B组件。这样是可以的,但是写法不太简易,层级多了就要递传。

2.2 发布订阅模式

// eventBus.js

class EventBus {
    constructor() {
        this.events = new Map();
    }

    // 订阅事件
    on(eventName, callback) {
        if (!this.events.has(eventName)) {
            this.events.set(eventName, []);
        }
        this.events.get(eventName).push(callback);
    }

    // 取消订阅
    off(eventName, callback) {
        if (!this.events.has(eventName)) return;
        const callbacks = this.events.get(eventName);
        const index = callbacks.indexOf(callback);
        if (index !== -1) {
            callbacks.splice(index, 1);
        }
    }

    // 发布事件
    emit(eventName, ...args) {
       const callbacks = this.events.get(eventName) || [];
       callbacks.forEach(callback => callback(...args));
    }
}

export default new EventBus();

2.3 使用mitt

安装依赖

npm install mitt

2.3.1 全局使用

//main.js
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import mitt from 'mitt'

const emitter = mitt()

const app = createApp(App)
app.config.globalProperties.$EventBus = emitter

app.mount('#app')

<!-- ComponentA.vue -->
<script setup>
import { ref,getCurrentInstance } from 'vue'
const message = ref('')
const { proxy } = getCurrentInstance()
const sendMessage2 = () => {
  proxy.$EventBus.emit('new-message', message.value)
  message.value = ''
}
onBeforeUnmount(() =>{
  proxy.$EventBus.off('new-message')
})
</script>
<template>
  <div>
    <input v-model="message" placeholder="输入消息" />
    <button @click="sendMessage2">发送消息2</button>
  </div>
</template>

<!-- ComponentB.vue -->
<script setup>
import { ref, onMounted, onUnmounted,getCurrentInstance } from 'vue'
const receivedMessages = ref([])
const {proxy} = getCurrentInstance()

const onNewMessage = (msg) => {
  receivedMessages.value.push(msg)
}
onMounted(() => {
  proxy.$EventBus.on('new-message', onNewMessage)
})
onUnmounted(() => {
  proxy.$EventBus.off('new-message', onNewMessage)
})
</script>
<template>
  <div>
    <h2>接收到的消息:</h2>
    <ul>
      <li v-for="(msg, index) in receivedMessages" :key="index">{{ msg }}</li>
    </ul>
  </div>
</template>

2.3.2 局部使用

// eventBus.js
import { ref } from 'vue'
import mitt from 'mitt'

const emitter = mitt()
const bus = ref(emitter)

export default bus

<!-- ComponentA.vue -->
<script setup>
import { ref, getCurrentInstance, onBeforeUnmount } from 'vue'
import bus from '../eventBus'

const message = ref('')
const { proxy } = getCurrentInstance()

const sendMessage = () => {
  bus.value.emit('new-message', message.value)
  message.value = ''
}

const sendMessage2 = () => {
  proxy.$EventBus.emit('new-message', message.value)
  message.value = ''
}
onBeforeUnmount(
  () => {
    proxy.$EventBus.off('new-message')
    bus.value.off('new-message')
  }
)

</script>

<template>
  <div>
    <input v-model="message" placeholder="输入消息" />
    <button @click="sendMessage">发送消息</button>
    <button @click="sendMessage2">发送消息2</button>
  </div>
</template>

<!-- ComponentB.vue -->
<script setup>
import { ref, onMounted, onUnmounted,getCurrentInstance } from 'vue'
import bus from '../eventBus'

const receivedMessages = ref([])
const {proxy} = getCurrentInstance()

const onNewMessage = (msg) => {
  receivedMessages.value.push(msg)
}

onMounted(() => {
  proxy.$EventBus.on('new-message', onNewMessage)
  bus.value.on('new-message', onNewMessage)
})

onUnmounted(() => {
  proxy.$EventBus.off('new-message', onNewMessage)
  bus.value.off('new-message', onNewMessage)
})
</script>

<template>
  <div>
    <h2>接收到的消息:</h2>
    <ul>
      <li v-for="(msg, index) in receivedMessages" :key="index">{{ msg }}</li>
    </ul>
  </div>
</template>

其实试了下,两个都可以一起用。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2221352.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jmeter使用文档

文章目录 一、安装使用1、下载2、bin/jmeter.properties介绍 二、windows使用1、微调&#xff08;1&#xff09;界面样式&#xff08;2&#xff09;修改语言 2、简单使用3、各组件详解&#xff08;1&#xff09;CSV 数据文件配置&#xff08;2&#xff09;BeanShell取样器 三、…

【Linux线程】Linux多线程实践:深入生产者消费者模型

&#x1f4dd;个人主页&#x1f339;&#xff1a;Eternity._ ⏩收录专栏⏪&#xff1a;Linux “ 登神长阶 ” &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; ❀Linux多线程 &#x1f4d2;1. 生产者消费者模型&#x1f4dc;2. 基于BlockingQueue的生产者消…

BurpSuite渗透工具的简单使用

BurpSuite渗透工具 用Burp Suite修改请求 step1&#xff1a; 安装Burp Suite。官网链接&#xff1a;Burp Suite官网 step2&#xff1a; 设置代理 step3&#xff1a; 如果要拦截https请求&#xff0c;还需要在客户端安装证书 step4&#xff1a; 拦截到请求可以在Proxy ->…

进程地址空间与页表

目录 引言 问题导入 进程地址空间 宏观的过程去分析 谈细节 1.进程地址空间究竟是什么 2.页表 3.进程被挂起 4.页表的存在&#xff0c;让进程管理和内存管理相连动 本文核心逻辑 引言 在当今的计算世界中&#xff0c;操作系统是管理计算机硬件和软件资源的关键组件。而…

联想与Meta合作基于Llama大模型推出面向PC的个人AI智能体——AI Now | LeetTalk Daily...

“LeetTalk Daily”&#xff0c;每日科技前沿&#xff0c;由LeetTools AI精心筛选&#xff0c;为您带来最新鲜、最具洞察力的科技新闻。 联想集团昨日在美国西雅图召开年度Tech World大会。联想CEO杨元庆在主题演讲中&#xff0c;与Meta创始人兼CEO马克扎克伯格一道宣布&#x…

MYSQL-建库、建表,并创建表的详细信息

首先&#xff0c;创建一个&#xff1a;图书管理系统数据库。 1、创建用户表&#xff1a; 2、创建图书表&#xff1a; 3、创建借阅登记表&#xff1a;

Android使用协程实现自定义Toast

Android使用协程实现自定义Toast ​ 最近有个消息提示需要显示10s,刚开始使用协程写了一个shoowToast方法&#xff0c;传入消息内容、显示时间和toast显示类型即可&#xff0c;以为能满足需求&#xff0c;结果测试说只有5s&#xff0c;查看日志和源码发现Android系统中Toast显…

尚硅谷spark学习

p4 快速上手 -开发环境准备

基于工业互联网平台的智能工厂辅助制造企业数字化转型

制造业数字化转型已是大势所趋&#xff0c;工业互联网平台对于制造业数字化转型的支撑作用将会越来越强&#xff0c;其应用为制造企业生产和运营优化的能力提升提供了探索应用模式和路径。平台的不断创新和应用突破&#xff0c;将不断为制造业的升级转型赋能。实施制造业数字化…

C#线程详解及应用示例

简介 在编写应用程序实现业务功能过程中&#xff0c;为解决吞吐量和响应效率的问题&#xff0c;我们会用到多线程、异步编程两项重要的技术。通过它们来提高应用程序响应和高效。应用程序每次运行都会启动一个进程&#xff08;进程是一种正在执行的程序&#xff09;&#xff0…

基于node.js宜家宜业物业管理系统【附源码】

基于node.js宜家宜业物业管理系统 效果如下&#xff1a; 系统首页界面 业主登录界面 停车位页面 小区公告页面 管理员登录界面 管理员功能界面 物业管理员管理界面 缴费信息管理界面 物业管理员功能界面 研究背景 近年来互联网技术飞速发展&#xff0c;给人们的生活带来了极…

【数据分享】全国金融业-股票发行量和筹资额(1991-2021年)

数据介绍 一级标题指标名称单位金融业股票发行量亿股金融业A股发行量亿股金融业H股,N股发行量亿股金融业B股发行量亿股金融业股票筹资额亿元金融业A股筹资额亿元金融业配股筹资额亿元金融业H股,N股筹资额亿元金融业B股筹资额亿元 注&#xff1a;本文中的数据仅为示例&#xf…

Burp Suite Professional 2024.9 for macOS x64 ARM64 - 领先的 Web 渗透测试软件

Burp Suite Professional 2024.9 for macOS x64 & ARM64 - 领先的 Web 渗透测试软件 世界排名第一的 Web 渗透测试工具包 请访问原文链接&#xff1a;https://sysin.org/blog/burp-suite-pro-mac/ 查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1…

【数据结构】分治算法经典: 快速排序详解

快速排序&#xff08;Quicksort&#xff09;是一种高效的排序算法&#xff0c;最早由Tony Hoare在1960年提出。它采用了分治&#xff08;Divide and Conquer&#xff09;策略&#xff0c;平均时间复杂度为 O ( n log ⁡ n ) O(n \log n) O(nlogn)&#xff0c;在大多数实际应用…

双十一开启极速达夜派;黑神话获泰国年度最佳游戏;AI 模型可帮助识别 17000 多种疾病的候选药物....| 网易数智日报

双 11 菜鸟在北京、上海、广州、杭州等城市开启「预售极速达夜派」服务 10 月 21 日&#xff0c;菜鸟在北京、上海、广州、杭州等城市开启「预售极速达夜派」服务&#xff0c;批量大促包裹实现小时级送达。 据介绍&#xff0c;在消费者支付尾款前&#xff0c;菜鸟供应链就已经…

项目结构(后端+前端)(若依)

项目结构&#xff08;后端前端&#xff09; 文章目录 项目结构&#xff08;后端前端&#xff09;前言一、后端结构1.若依 二、前端结构1. 总结 前言 方便了解项目结构 提示&#xff1a;以下是本篇文章正文内容&#xff1a; 一、后端结构 1.若依 com.ruoyi ├── ruoyi-adm…

【C++干货篇】——类和对象的魅力(四)

【C干货篇】——类和对象的魅力&#xff08;四&#xff09; 1.取地址运算符的重载 1.1const 成员函数 将const修饰的成员函数称之为const成员函数&#xff0c;const修饰成员函数放到成员函数参数列表的后面。const实际修饰该成员函数隐含的this指针&#xff08;this指向的对…

Flutter Container容器组件实战案例

The Container widget is your design toolkit. It’s like the master builder that helps you structure and style your UI elements with precision. Whether you’re creating simple designs or complex layouts, the Container is your trusty tool for the job. “容器…

全能大模型GPT-4o体验和接入教程

GPT-4o体验和接入教程 前言一、原生API二、Python LangchainSpring AI总结 前言 Open AI发布了产品GPT-4o&#xff0c;o表示"omni"&#xff0c;全能的意思。 GPT-4o可以实时对音频、视觉和文本进行推理&#xff0c;响应时间平均为 320 毫秒&#xff0c;和人类之间对…

【C++篇】深度解析类与对象(上)

目录 引言 一、类的定义 1.1类定义的基本格式 1.2 成员命名规范 1.3 class与struct的区别 1.4 访问限定符 1.5 类的作用域 二、实例化 2.1 类的实例化 2.2 对象的大小与内存对齐 三、this 指针 3.1 this指针的基本用法 3.2 为什么需要this指针&#xff1f; 3.3 t…