vue3-组件之间的通信

news/2024/11/29 8:55:08/

1、父 传 子:props

父: 传入 msg 和 school信息

<Demo msg="圣墟" school="陈东" />

子:接收 信息,可直接{{msg}} 使用

const props = defineProps(['msg','school'])

2、子传父(自定义事件)

父: 使用自定义事件xxx 和 事件触发的函数handler

<Demo msg="圣墟" school="陈东" @xxx="handler"/>function handler(p1,p2){console.log(p1,p2)
}

子:
定义自定义事件xxx,当点击school时触发点击事件 handler,handler 触发自定义事件,将参数 传给父组件

<template><div><h2 @click="handler">school:{{ school }}</h2></div>
</template><script setup>
import { reactive } from "vue";const props = defineProps(['msg','school'])
let a1 = defineEmits(["xxx"]) // 定义自定义事件
function handler(){a1("xxx",1,2,3)}

3、全局总线通信(组件相互通信 ,mitt)

1、安装mitt

npm install --save mitt

2、新建 mitt.ts文件

// 引入 mitt插件:mitt是一个方法,返回bus对象
import mitt from "mitt";
const $bus = mitt()
export default $bus

3、发消息方

<template><div><h1>子组件1</h1><button @click="sendMsg"> 点我给组件传递参数</button></div>
</template><script setup>
import $bus from "../bus";function sendMsg(){$bus.emit('msg',{info:"我是你大哥"})
}</script><style></style>

4、收消息方

import $bus from '../bus';
import {onMounted} from "vue"// 组件挂载完毕后 接收兄弟组件传的数据
onMounted(() => {$bus.on("msg",(msg) =>{console.log(msg)})
})

4、useAttrs获取父组件使用子组件的属性值

父:
使用子组件,并给予属性 type等

<HintButton type="primary" size ='small' :icon="Edit" title="编辑按钮" @click="handler"></HintButton>

子:通过useAttrs方法获取属性数组

<template><el-button type="AttrArr.type" >123</el-button><el-button :="AttrArr" >123</el-button>
></template><script setup lang="ts">// 引入 useAttrs方法,获取组件传递的属性和事件
import {useAttrs} from 'vue'let AttrArr = useAttrs();
console.log(AttrArr)</script>

注意 useAttrs 和 props 都可以实现此功能 但 props优先级更高,当 props 获取一个值时,这个值 useAttrs 就拿不到了

5、ref & $parent

ref :可以获取真实dom节点 和 子组件的实例 vc(获取其数据和方法)
子组件

<template>
<h1>son 的钱数{{ money }}</h1>
</template><script setup lang="ts">
import { ref } from 'vue';
let money = ref(666)const fly = ()=>{console.log('i can fly')
}
// 组件内部数据默认对外关闭,别人不能访问,
// defineExpose 配置对外暴露数据
defineExpose({money,fly
})</script>
<style></style>

父组件

<template><h1>father has {{ money }}</h1><HintButton ref="son"></HintButton><button @click="getMoney">点我借儿子 10块钱</button>
</template><script setup lang ="ts">
import HintButton from './HintButton.vue';
import { ref } from 'vue';let money = ref(10000)// 获取子组件的 实例VC
let son = ref()const getMoney = ()=>{money.value += 10console.log(son.value)son.value.money -= 10 // 获取 子组件数据son.value.fly() // 调用子组件的方法
}
</script><style></style>

$parent:可以在 子组件内部获取 父组件的实例

子组件

注意:子组件可以被多次引用,所以可能有多个父组件,此时 获取到的父组件:哪个父组件触发了这个子组件的点击事件,参数就是哪个父组件

<template>
<h1>son 的钱数{{ money }}</h1><!-- ($parent) 获取父组件 实例 -->
<button @click="getMoney($parent)">点我 老爸给我10钱</button>
</template><script setup lang="ts">
import { ref } from 'vue';
let money = ref(666)// 参数是父组件 VC 
//  注意:子组件可以被多次引用,所以可能有多个父组件,此时 获取到的父组件:哪个父组件触发了这个子组件的点击事件,参数就是哪个父组件
const getMoney = ($parent)=>{money.value += 10console.log($parent)$parent.money  -= 10
}</script>
<style></style>

父组件

<template><h1>father has {{ money }}</h1><HintButton ></HintButton></template><script setup lang ="ts">
import HintButton from './HintButton.vue';
import { ref } from 'vue';let money = ref(10000)// 对外暴露数据
defineExpose({money
})</script><style></style>

6、provide & inject(子获取父传的数据)

父组件

provide 方法 发送数据

<template><h1>father has {{ money }}</h1><HintButton ></HintButton></template><script setup lang ="ts">
import HintButton from './HintButton.vue';
import { ref ,provide} from 'vue';let money = ref(10000)
provide("money",money.value)</script><style></style>

子组件

inject方法接收数据(可修改父组件数据)

<template>
<h1>son 的钱数{{ money }}</h1><!--  -->
</template><script setup lang="ts">
import { ref,inject } from 'vue';
let money = ref(666)console.log("儿子知道你有多少钱了",inject("money"))</script>
<style></style>

7、pinia 实现仓库数据供组件调用

1、选项式

1、src下创建 store 文件夹,下创建 index.ts 总仓库

import { createPinia } from "pinia";// 创建大仓库
let store = createPinia();// 对外暴露仓库
export default store

2、同目录下创建 子仓库info.ts

state:存放数据
actions:定义仓库的方法,组件可以调用
getter:计算属性数据

// 定义info小仓库
import { defineStore } from "pinia";// 第一个参数 小仓库的名字  第二个参数 小仓库配置的对象
let infoStore = defineStore("info",{// 存储数组 :statestate: () => {return {count:99,arr : [1,2,3,4,5,6]}},// 定义仓库的方法actions:{updateInfoStore(a:number,b:number){this.count += (a+b)}},// 计算属性:数组求和getters:{Sum(){let sum:any = this.arr.reduce((prev:number,next:number) =>{return prev + next},0)return sum}}})// 对外暴露小仓库
export default infoStore

3、main.ts


// 引入 仓库
import store from './store'
app.use(store)

4、组件使用仓库数据 方法

<template><!-- 使用仓库数据 -->
<h1>{{ infoStore1.count }}</h1> 
<h1>{{ infoStore1.Sum }}</h1>
<button @click="updateInfoStore">修改仓库数据</button></template><script setup lang="ts">
import { ref } from 'vue';
// 导入 仓库对象
import infoStore from '@/store/info';// 定义仓库对象
let infoStore1 = infoStore()const updateInfoStore = () =>{// 调用仓库方法infoStore1.updateInfoStore(1,2) 
}</script>
<style></style>

2、组合式 写法

1、store下创建 todo.ts

import { defineStore } from "pinia";
import { computed, ref } from "vue";// 创建小仓库
let todoStore = defineStore("todo",() =>{let arr = [{id:1,title:'car'},{id:2,title:'bus'}]let todos = ref(arr)// 组合式 计算属性const count = computed(() =>{return arr.length})// 返回一个对象,属性和方法为组件所用return {arr,count,todos,updateTodo(a:any){  // 组合式方法this.arr.push(a)}}
})export default todoStore

2、组件使用组合式

<template><p @click="updateTodo">{{ todo.todos }}</p>
<h1>数组的大小:{{ todo.count }}</h1>
</template><script setup lang="ts">
import { ref,computed } from 'vue';
// 导入 仓库对象
import todoStore from '@/store/todo';let todo = todoStore()const updateTodo = () =>{let a = {id:3,title:"plan"}todo.updateTodo(a)
}</script>
<style></style>

3、总仓库 index.ts 和main.ts 同 选项式

8、插槽(父 = > 子)

1、默认插槽

父组件:
<son>
<div>我是默认插槽 </div>
</son>子组件:son
<div>
<slot></slot> // 使用父组件的插槽内容
</div>

2、具名插槽

父组件:<son><template v-slot:a>  //可以用#a替换<div>填入组件A部分的结构</div></template><template v-slot:b>//可以用#b替换<div>填入组件B部分的结构</div></template></son>子组件:son<div><slot name="a"></slot><slot name="b"></slot></div>
</template>

3、作用域插槽

子组件数据由父组件提供,
但是子组件内部决定不了自身结构与外观(样式),由父组件决定

示例:
父组件将数组对象传给 子组件,子组件对数组进行遍历 列表展示
并把每行数据传给父组件 ,由父组件觉得样式(已经做的 green。没做的 red)

子组件

<template><div><h1>todo</h1><ul><!--组件内部遍历数组--><li v-for="(item,index) in todos" :key="item.id"><!--作用域插槽将数据回传给父组件--><slot :$row="item" :$index="index"></slot></li></ul></div>
</template>
<script setup lang="ts">
defineProps(['todos']);//接受父组件传递过来的数据
</script>
<style scoped>
</style>

父组件:

<template><div><h1>slot</h1><Todo :todos="todos"><template v-slot="{$row,$index}"><!--父组件决定子组件的结构与外观--><span :style="{color:$row.done?'green':'red'}">{{$row.title}}</span></template></Todo></div>
</template><script setup lang="ts">
import Todo from "./Todo.vue";
import { ref } from "vue";
//父组件内部数据
let todos = ref([{ id: 1, title: "吃饭", done: true },{ id: 2, title: "睡觉", done: false },{ id: 3, title: "打豆豆", done: true },
]);
</script>
<style scoped>
</style>

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

相关文章

【C++】结构体 - 定义和使用,结构体数组,结构体指针,结构体嵌套结构体,结构体做函数参数,结构体const

文章目录 1. 定义和使用2. 结构体数组3. 结构体指针4. 结构体嵌套结构体5. 结构体做函数参数6. 结构体const 1. 定义和使用 结构体属于用户自定义的数据类型&#xff0c;允许用户存储不同的数据类型。 struct 结构体 {结构体成员列表}; 通过结构体创建变量的方法有三种&…

MATLAB机器学习:分类、回归和聚类的算法实现和模型优化

第一章&#xff1a;引言 机器学习是当今IT领域最热门的话题之一&#xff0c;它为我们提供了解决复杂问题的新方法。MATLAB作为一种功能强大的编程语言和环境&#xff0c;提供了许多用于机器学习的工具和函数。本文将介绍MATLAB中常用的分类、回归和聚类算法的实现&#xff0c;…

RK3588平台开发系列讲解(基础篇)Linux 内核有多少 API 接口

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、Linux 内核有多少 API 接口二、Linux 系统调用表三、Linux 系统调用实现3.1、申明系统调用3.2、定义系统调用沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 Linux 作为比较成熟的操作系统,功能完善,它…

安装VMware Workstation和虚拟机教程

一、VM简介   VMware Workstation中文版是一个“虚拟 PC”软件。它使你可以在一台机器上同时运行二个或更多 Windows、DOS、LINUX 系统。与“多启动”系统相比&#xff0c;VMWare 采用了完全不同的概念。多启动系统在一个时刻只能运行一个系统&#xff0c;在系统切换时需要重…

jenkins配置邮箱

1.邮箱需要支持SMTP协议&#xff0c;以163邮箱为例 邮箱开通SMTP协议&#xff0c;生成秘钥 2.jenkins进入system拉到最下方&#xff0c;E-mail Notification SMTP server:邮箱smtp服务器地址&#xff08;smtp.163.com&#xff09; Default user e-mail suffix&#xff1a;邮箱…

nodejs基于vue的医院在线挂号系统

本设计是在win10操作系统环境下&#xff0c;采取nodejs作为主要编程环境&#xff0c;通过nodejs语言使用sxpress框架&#xff0c;实现医院预约挂号系统。首先用户需要选定一个医生进行预约&#xff0c;医生可以通过预约&#xff0c;这里涉及到用户到医生的数据传输&#xff0c;…

【Nginx】负载均衡

文章目录 负载均衡概述负载均衡的原理及处理流程负载均衡常用的处理方式方式一:用户手动选择方式二:DNS轮询方式方式三:四/七层负载均衡 Nginx七层负载均衡的指令upstream指令server指令 Nginx七层负载均衡的实现流程负载均衡状态负载均衡策略负载均衡案例案例一&#xff1a;对…

MySQL 事务篇

事务有哪些特性&#xff1f; 原子性&#xff1a; 一个事务中的所有操作&#xff0c;必须全部执行。要么全部完成要么就不完成。中间如果出现错误&#xff0c;就要回滚到初始状态。 持久性&#xff1a; 事务处理结束后&#xff0c;对数据的修改就是永久的&#xff0c;就是系统故…