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
      ><input
        type="text"
        @blur="checkUserName"
        v-model="username"
        placeholder="请输入用户名"
      />
      <span :class="[this.errors.username == '校验通过' ? 'green' : 'red']">{{
        errors.username
      }}</span>
    </li>
    <li>
      <label>密码:</label
      ><input
        type="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>

最终效果:

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Vue3兄弟组件之间传参有多种方法。其一种方法是通过使用插件mitt来实现。这个插件可以用于在不同组件之间进行事件的发布和订阅。首先,在父组件A,我们可以使用mitt插件创建一个事件总线,并将需要传递的数据作为参数发布到事件总线上。然后,在兄弟组件B,我们可以订阅这个事件,并在回调函数接收到传递的数据。通过这种方式,就可以实现兄弟组件之间的传参。 另一种实现兄弟组件传参的方法是通过使用provide和inject函数。在父组件A,我们可以使用provide函数将需要传递的数据提供给子组件B。然后,在组件B,我们可以使用inject函数来接收这些数据。通过这种方式,兄弟组件之间可以共享数据。这种方法比较适合多层级之间的组件传参。 总结起来,Vue3兄弟组件传参的方法包括使用mitt插件和使用provide和inject函数。通过这些方法,可以实现不同组件之间的数据传递和共享。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Vue和React组件之间的传值方式详解](https://download.csdn.net/download/weixin_38685961/14812277)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Vue3兄弟组件传值](https://blog.csdn.net/qq_43575827/article/details/131529569)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

⁡⁢⁡⁢⁠Ac

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值