一.vue3中的组件通信方式
比如:vue2组件通信方式
**props:**可以实现父子组件、子父组件、甚至兄弟组件通信
自定义事件:可以实现子父组件通信
全局事件总线$bus:可以实现任意组件通信,很重要
**pubsub:**发布订阅模式实现任意组件通信,不常用
vuex:集中式状态管理容器,实现任意组件通信
ref:父组件获取子组件实例VC,获取子组件的响应式数据以及方法
**slot:**插槽(默认插槽、具名插槽、作用域插槽)实现父子组件通信…
但我们下边介绍的是vue3
中的组件通信方式
1.props —— defineProps
1)子组件获取父组件传递数据
方式1
let props = defineProps({
info:{
type:String,//接受的数据类型
default:'默认参数',//接受默认数据
},
money:{
type:Number,
default:0
}})
方式2
let props = defineProps(["info",'money']);
2)注意
- 组合式api需要使用到
defineProps
方法去接受父组件传递过来的数据,他是Vue3提供方法,不需要引入直接使用 - 使用的时候,在template使用可以直接省略props;但在script使用的时候,不能省略。这里的props是代理对象
- props是只读的,不能修改
3)案例
父:
<template>
<div class="box">
<h1>props:我是父组件曹操</h1>
<hr />
<Child info="我是曹操" :money="money"></Child>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import {
ref } from "vue";
let money = ref(10000);
</script>
<style scoped>
</style>
子:
<template>
<div class="son">
<h1>我是子组件:曹植</h1>
<p>{
{
props.info}}</p>
<p>{
{
props.money}}</p>
<!--下面省略可以--->
<p>{
{
info}}</p>
<p>{
{
money}}</p>
</div>
</template>
<script setup lang="ts">
let props = defineProps(['info','money']); //数组|对象写法都可以
</script>
2.自定义事件 —— defineEmits
在vue框架中事件分为两种:一种是原生的DOM事件
,另外一种自定义事件
。
原生DOM事件
可以让用户与网页进行交互,比如click、dbclick、change、mouseenter、mouseleave…
自定义事件
可以实现子组件给父组件传递数据
1)参数
<!-- 原生DOM事件 -->
<pre @click="handler">
大江东去浪淘尽,千古分流人物
</pre>
<Event1 @click="handler2"></Event1>
利用defineEmits
方法返回函数触发自定义事件,defineEmits
方法不需要引入直接使用
第一个参数:事件类型 第二个|三个|N参数即为注入数据
$emit('xxx','东风导弹','航母');
2)注意
vue2框架当中,自定义事件,可以通过.native修饰符变为原生DOM事件
vue3框架下面写法其实即为原生DOM事件,原生的DOM事件不管是放在标签身上、组件标签身上都是原生DOM事件
3)案例
父:
<template>
<div>
<h1>事件</h1>
<!-- 原生DOM事件 -->
<pre @click="handler">
大江东去浪淘尽,千古分流人物
</pre>
<button @click="handler1(1,2,3,$event)">点击我传递多个参数</button>
<hr>
<!-- 也是原生DOM事件 -->
<Event1 @click="handler2"></Event1>
<hr>
<!-- 绑定两个自定义事件xxx和click:实现子组件给父组件传递数据 -->
<Event2 @xxx="handler3" @click="handler4"></Event2>
</div>
</template>
<script setup lang="ts">
import Event1 from './Event1.vue';
import Event2 from './Event2.vue';
//原生DOM事件
const handler = (event)=>{
//event即为事件对象
console.log(event);
}
//原生DOM事件传递多个参数
const handler1 = (a,b,c,$event)=>{
console.log(a,b,c,$event)
}
//原生DOM事件
const handler2 = ()=>{
console.log(123);
}
//自定义事件
const handler3 = (param1,param2)=>{
console.log(param1,param2);
}
//自定义事件
const handler4 = (param1,param2)=>{
console.log(param1,param2);
}
</script>
<style scoped>
</style>
Event1:
<template>
<div class="son">
<p>我是子组件1</p>
<button>点击我也执行</button>
</div>
</template>
Event2:
<template>
<div class="child">
<p>我是子组件2</p>
<button @click="handler">点击我触发自定义事件xxx</button>
<button @click="$emit('click','AK47','J20')">点击我触发自定义事件click</button>
</div>
</template>
<script setup lang="ts">
//这里click被注册为了自定义事件了,那么就不是原生DOM事件了
let $emit = defineEmits(['xxx','click']);
//按钮点击回调
const handler = () => {
//第一个参数:事件类型 第二个|三个|N参数即为注入数据
$emit('xxx','东风导弹','航母');
};
</script>
3.全局事件总线 —— $bus
全局事件总线可以实现任意组件通信,在vue2中可以根据VM与VC关系推出全局事件总线。
但是在vue3中没有Vue构造函数,也就没有Vue.prototype.以及组合式API写法没有this,
vue2中全局事件总线的使用
那么在Vue3想实现全局事件的总线功能就有点不现实啦,如果想在Vue3中使用全局事件总线功能
可以使用插件mitt实现。
1)参数
第一个参数:即为事件类型 第二个参数:即为事件回调
$bus.on("car", (car) => {
console.log(car);
}