VUE框架组件中通信方式(2)
全局事件总线
全局事件总线可以实现任意组件通信,在vue2中可以根据VM与VC的关系推出全局事件总线。
点击查看全局事件总线代码示例
// main.js
import Vue from 'vue'
import App from './App.vue'
// 创建一个Vue实例作为事件总线
export const eventBus = new Vue()
new Vue({
render: h => h(App),
}).$mount('#app')
<!-- ChildComponent.vue -->
<template>
<div>
<button @click="sendMessage">发送消息</button>
</div>
</template>
<script>
import { eventBus } from './main'
export default {
methods: {
sendMessage() {
// 通过事件总线发送消息
eventBus.$emit('message', 'Hello from ChildComponent')
}
}
}
</script>
<!-- ParentComponent.vue -->
<template>
<div>
<child-component></child-component>
<p>{{ receivedMessage }}</p>
</div>
</template>
<script>
import { eventBus } from './main'
export default {
data() {
return {
receivedMessage: ''
}
},
mounted() {
// 通过事件总线监听消息
eventBus.$on('message', message => {
this.receivedMessage = message
})
}
}
</script>
点击查看代码
//安装:$ npm install --save mitt
//引入mitt插件:mitt一个方法,方法执行会返回bus对象(新建bus.ts文件)
import mitt from 'mitt';
const $bus = mitt();
export default $bus;
//=================================
//父组件代码
<template>
<div class="box">
<h1>全局事件总线$bus</h1>
<hr />
<div class="container">
<Child1></Child1>
<Child2></Child2>
</div>
</div>
</template>
<script setup lang="ts">
//引入子组件
import Child1 from "./Child1.vue";
import Child2 from "./Child2.vue";
</script>
//=================================
//child1文件代码
<template>
<div class="child1">
<h3>我是子组件1:曹植+{{ ccar }}</h3>
</div>
</template>
<script setup lang="ts">
import $bus from "../../bus";
//组合式API函数
import { ref,onMounted, type Ref } from "vue";
//组件挂载完毕的时候,当前组件绑定一个事件,接受将来兄弟组件传递的数据
let ccar:Ref = ref("宾利")
onMounted(() => {
//第一个参数:即为事件类型 第二个参数:即为事件回调
$bus.on("car", (car) => {
console.log(car);
ccar.value = car
});
});
</script>
//child2文件代码
<template>
<div class="child2">
<h2>我是子组件2:曹丕</h2>
<button @click="handler">点击我给兄弟送一台法拉利</button>
</div>
</template>
<script setup lang="ts">
//引入$bus对象
import $bus from '../../bus';
//点击按钮回调
const handler = ()=>{
$bus.emit('car',{car:"法拉利"});
}
</script>
v-model数据传递
v-model指令:多用于收集表单数据,数据双向绑定
v-model也可以实现组件之间的通信,实现父子组件数据同步的业务
正常逻辑上父与子同步数据,应该是父组件在子组件标签属性上将值传递给子组件,子组件用props接收传递的值,同时在父组件的子组件标签上定义自定义事件,然后在子组件中使用emit函数将数据通过自定义事件传递回父组件。
示例代码如下:
//父组件代码
<template>
<Child :modelValue="money" @update:modelValue="handler"></Child>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import { ref } from "vue";
let money = ref(10000);
//自定义事件的回调
const handler = (num) => {
//将来接受子组件传递过来的数据
money.value = num;
};
</script>
//子组件代码
<template>
<div class="child">
<h3>钱数:{{ modelValue }}</h3>
<button @click="handler">父子组件数据同步</button>
</div>
</template>
<script setup lang="ts">
//接受props
let props = defineProps(["modelValue"]);
let $emit = defineEmits(['update:modelValue']);
//子组件内部按钮的点击回调
const handler = ()=>{
//触发自定义事件
$emit('update:modelValue',props.modelValue+1000);//将数据回传给handler的num中
}
</script>
如果使用v-model来同步父子组件的数据的话,v-model相当于什么?
第一:相当有给子组件传递props[modelValue]
第二:相当于给子组件绑定自定义事件update:modelValue
示例代码如下
//父组件代码
<template>
<div>
<h1>v-model:钱数{{ money }}{{pageNo}}{{pageSize}}</h1>
<input type="text" v-model="info" />
<hr />
<!-- props:父亲给儿子数据 -->
<!-- <Child :modelValue="money" @update:modelValue="handler"></Child> -->
<!--
v-model组件身上使用
第一:相当有给子组件传递props[modelValue] = 10000
第二:相当于给子组件绑定自定义事件update:modelValue
-->
<Child v-model="money"></Child>
<hr />
<Child1 v-model:pageNo="pageNo" v-model:pageSize="pageSize"></Child1>
</div>
</template>
<script setup lang="ts">
//v-model指令:收集表单数据,数据双向绑定
//v-model也可以实现组件之间的通信,实现父子组件数据同步的业务
//父亲给子组件数据 props
//子组件给父组件数据 自定义事件
//引入子组件
import Child from "./Child.vue";
import Child1 from "./Child1.vue";
import { ref } from "vue";
let info = ref("");
//父组件的数据钱数
let money = ref(10000);
//自定义事件的回调
const handler = (num) => {
//将来接受子组件传递过来的数据
money.value = num;
};
//父亲的数据
let pageNo = ref(1);
let pageSize = ref(3);
</script>
//===============================
//子组件代码Child文件
<template>
<div class="child">
<h3>钱数:{{ modelValue }}</h3>
<button @click="handler">父子组件数据同步</button>
</div>
</template>
<script setup lang="ts">
//接受props
let props = defineProps(["modelValue"]);
let $emit = defineEmits(['update:modelValue']);
//子组件内部按钮的点击回调
const handler = ()=>{
//触发自定义事件
$emit('update:modelValue',props.modelValue+1000);
}
</script>
//子组件Child1文件
<template>
<div class="child2">
<h1>同时绑定多个v-model</h1>
<button @click="handler">pageNo{{ pageNo }}</button>
<button @click="$emit('update:pageSize', pageSize + 4)">
pageSize{{ pageSize }}
</button>
</div>
</template>
<script setup lang="ts">
let props = defineProps(["pageNo", "pageSize"]);
let $emit = defineEmits(["update:pageNo", "update:pageSize"]);
//第一个按钮的事件回调
const handler = () => {
$emit("update:pageNo", props.pageNo + 3);
};
</script>

浙公网安备 33010602011771号