> 文章列表 > Vue3中使用 EventBus 实现兄弟组件传参

Vue3中使用 EventBus 实现兄弟组件传参

Vue3中使用 EventBus 实现兄弟组件传参

前言:EventBus vue3中没有了,EventBus,所以我们要自己写,但是非常简单。

步骤一:创建(EventBus 容器)

在src目录,创建个bus文件夹,存放 自己建立的 bus.js 

class Bus {constructor() {this.list = {};  // 收集订阅}// 订阅$on(name, fn) {this.list[name] = this.list[name] || [];this.list[name].push(fn);}// 发布$emit(name, data) {if (this.list[name]) {this.list[name].forEach((fn) => {	fn(data);   });}}// 取消订阅$off(name) {if (this.list[name]) {delete this.list[name];}}
}
export default new Bus;

步骤二:创建(发布者)

调用订阅 并且传参数   记住:需要引入Bus.js文件

  Bus.$emit('userinfo',this.users);

发布后,在订阅者的组件就会执行,注意对应的发布和订阅的name 要一样

步骤三:创建(订阅者)

发布之后开始执行  记住:也是需要引入Bus.js文件

mounted() {Bus.$on("userinfo", (userinfo) => {this.userinfo = userinfo;});},

完整代码:

父组件:

<template><Send/><On/></template><script>
import Send from "./components/Send.vue";
import On from "./components/On.vue";
export default {name: "App",components: {Send,On},
}
</script><style></style>

兄弟组件1 (发送方):

<template><h3>用户注册</h3><ul><li><label>用户名:</label><inputtype="text"@blur="checkUserName"v-model="username"placeholder="请输入用户名"/><span :class="[this.errors.username == '校验通过' ? 'green' : 'red']">{{errors.username}}</span></li><li><label>密码:</label><inputtype="password"@blur="checkPass"v-model="password"placeholder="请输入密码"/><span>{{ errors.password }}</span></li><li><label>性别:</label><input type="radio" name="gender" value="male" v-model="gender" />男<input type="radio" name="gender" value="female" v-model="gender" />女</li><li><label>地址:</label><select v-model="selectedCity"><option :value="c.name" v-for="c in cities">{{ c.text }}</option></select></li></ul><button @click="handleRegister">注册</button>
</template><script>
import Bus from "../bus/bus.js";
export default {data() {return {username: "",password: "",gender: "male",cities: [{ name: "cq", text: "重庆" },{ name: "bj", text: "北京" },],selectedCity: "cq",errors: {},id: "",users: [],};},methods: {handleModify() {const user = this.users.find((u) => {return u.id == this.id;});user.username = this.username;user.password = this.password;user.gender = this.gender;user.city = this.selectedCity;},handleRegister() {if (this.errors.username == "校验通过" &&this.errors.password == "校验通过") {console.log({username: this.username,password: this.password,gender: this.gender,city: this.selectedCity,});this.users.push({username: this.username,password: this.password,gender: this.gender,city: this.selectedCity,});console.log(this.users);Bus.$emit('userinfo',this.users);}},checkUserName() {if (this.username == "" || this.username == null) {this.errors.username = "用户名不能为空";} else {this.errors.username = "校验通过";}},checkPass() {if (this.password == "" || this.password == null) {this.errors.password = "密码不能为空";} else {if (this.password.length < 6) {this.errors.password = "密码长度不正确";} else {this.errors.password = "校验通过";}}},handleCity(name) {let text = "";this.cities.forEach((c) => {if (c.name == name) {text = c.text;}});return text;},},
};
</script><style>
li {list-style: none;
}.center {margin: 0 auto;width: 400px;text-align: center;
}.red {color: red;
}.green {color: green;
}
</style>

兄弟组件2 (接受方):

<template><div style="display: flex; flex-direction: row; justify-content: center"><table border="1"><tr><td>序号</td><td>用户名</td><td>性别</td><td>地址</td></tr><tr v-for="(u, index) in userinfo"><td>{{ index + 1 }}</td><td>{{ u.username }}</td><td>{{ u.gender == "male" ? "男" : "女" }}</td><td>{{ handleCity(u.city) }}</td></tr></table></div>
</template><script>
import Bus from "../bus/bus.js";
export default {data() {return {userinfo: [],};},methods: {handleCity(e) {if (e === "cq") {return "重庆";}if (e === "bj") {return "北京";}},},mounted() {Bus.$on("userinfo", (userinfo) => {this.userinfo = userinfo;});},
};
</script><style>
</style>

最终效果: