Vue3中跨组件传值(Mitt)

1.安装mitt

我使用的是yarn

yarn add mitt

2.在根目录下创建eventBus.js

// eventBus.js
import mitt from "mitt";

export const EventBus = mitt();

3.组件间进行传值与接收值

使用emit传值,使用on接收,最后不要忘记销毁,避免内存泄漏

<template>
  <div class="parent">
    <h3>A组件</h3>
    <button @click="handleClick">传递Content值</button>
  </div>
</template>

<script setup>
import { ref } from "vue";
import { EventBus } from "@/eventBus.js";

const content = ref("Hello Word");

const handleClick = () => {
  EventBus.emit("change-content", content);
};
</script>

<style lang="scss" scoped>
.parent {
  width: 200px;
  height: 200px;
  background-color: #ccc;
}
</style>
<template>
  <div class="nav">
    <h2>B组件</h2>
    <p>接受的数据:{{ contents }}</p>
  </div>
</template>

<script setup>
import { EventBus } from "@/eventBus.js";
import { onMounted, onUnmounted, ref } from "vue";
const contents = ref("");

const handleMessage = (data) => {
  console.log(data);
  contents.value = data.value;
};

onMounted(() => {
  EventBus.on("change-content", handleMessage);
});

onUnmounted(() => {
  EventBus.off("change-content");
});
</script>

<style lang="scss" scoped>
.nav {
  width: 200px;
  height: 200px;
  background-color: #ccc;
}
</style>

<think>嗯,用户想了解Vue3组件之间如何。我需要先回顾一下Vue3提供的各种方法,然后按照不同的场景来分类说明。首先,Vue3Vue2在方面有一些不同,比如移除了事件总线,改用mitt库。另外,组合式API的引入可能也会影响的方式。 首先,常见的父子组件应该包括props和事件。父组件通过props向下递数据,子组件通过emit事件向上递数据。这部分和Vue2类似,但可能有语法上的细微差别。需要确认在Vue3中props的用法是否变化,以及setup函数中如何使用props和emit。 然后是跨层级组件,可能需要用到provide和inject。这部分在Vue3中是否有改进?比如是否支持响应式数据,或者需要配合computed来使用。需要举例子说明如何正确使用。 接下来,兄弟组件之间的Vue3不再支持事件总线,所以应该推荐使用mitt或者状态管理工具,比如Vuex或Pinia。需要说明mitt的用法,以及如何替代原来的$on和$emit。 还有v-model的变化,Vue3中v-model可以支持多个参数,这可能用于父子组件的双向绑定,比如自定义组件中使用多个v-model。这需要详细说明,可能给出示例代码。 另外,expose和ref的组合使用也是Vue3的新特性,允许子组件暴露特定的方法或属性给父组件访问。这部分需要解释清楚,如何通过ref获取子组件实例,并通过expose限制暴露的内容。 最后,状态管理工具Vuex和Pinia的使用场景。是否需要详细说明Pinia作为Vue3推荐的状态管理库,以及其基本用法? 还要注意用户提供的引用内容,引用1、2、3中提到了props、mitt、provide/inject、expose/ref等方法,需要覆盖这些内容,并结合示例代码。同时,用户的问题集中在Vue3,所以需要区分Vue2和Vue3的不同点,比如事件总线的替代方案。 需要确保回答结构清晰,分点说明每种方法,应用场景,以及代码示例。最后生成相关问题,可能涉及优化、最佳实践或对比Vue2的区别等。 可能还需要检查是否有遗漏的方法,比如通过模板引用直接访问子组件的情况,但根据引用内容,似乎expose/ref已经覆盖。另外,是否需要提及插槽(slots)?不过用户的问题主要是,可能不需要涉及内容分发部分。 总结下来,回答的结构应该是: 1. 父子组件:props和emit 2. 父子组件双向绑定:v-model 3. 跨层级组件:provide/inject 4. 兄弟组件mitt或状态管理 5. expose/ref暴露方法 6. 状态管理(Vuex/Pinia) 每个部分给出简要说明和代码示例,然后列出相关问题。确保使用正确的中文术语,代码块使用正确的语法,并符合用户的格式要求,比如行内公式用$...$,独立公式用$$...$$,不过这个问题可能不涉及数学公式,所以可能不需要处理这点。但需要遵守用户的其他格式指令,比如引用标识。用户提供的引用中有三个来源,需要正确对应到回答中的引用标识,比如[^1]、[^2]、[^3],但实际回答中引用的内容可能来自这些引用,比如提到兄弟组件mitt时引用[^3]。 需要确保每个引用标识正确对应,比如在提到兄弟组件时引用[^1]和,而provide/inject引用[^3]等。可能需要检查用户提供的引用内容,引用1主要讲Vue2和Vue3的兄弟,引用2和3详细列举了Vue3的各种方法,所以回答中需要合理分配引用标注。</think>### Vue3 组件方法与实现详解 Vue3 提供了多种组件方式,适用于不同场景。以下是主要方法及实现示例: --- #### 一、父子组件 1. **Props 向下** 父组件通过属性绑定递数据,子组件通过 `defineProps` 接收: ```vue <!-- 父组件 --> <template> <Child :title="msg" /> </template> <script setup> import Child from &#39;./Child.vue&#39;; const msg = "Hello Vue3"; </script> <!-- 子组件 Child.vue --> <script setup> const props = defineProps({ title: String }); </script> ``` 适用于单向数据流场景[^2]。 2. **自定义事件向上** 子组件通过 `defineEmits` 定义事件,父组件监听事件: ```vue <!-- 子组件 Child.vue --> <script setup> const emit = defineEmits([&#39;update-data&#39;]); const sendData = () => { emit(&#39;update-data&#39;, { value: 123 }); }; </script> <!-- 父组件 --> <template> <Child @update-data="handleData" /> </template> ``` 适合子组件向父组件主动通信[^3]。 --- #### 二、双向绑定:v-model Vue3 支持多个 `v-model` 绑定: ```vue <!-- 父组件 --> <Child v-model:name="name" v-model:age="age" /> <!-- 子组件 Child.vue --> <script setup> defineProps([&#39;name&#39;, &#39;age&#39;]); const emit = defineEmits([&#39;update:name&#39;, &#39;update:age&#39;]); </script> ``` 用于表单类组件的双向同步。 --- #### 三、跨层级组件 使用 `provide` 和 `inject`: ```vue <!-- 祖先组件 --> <script setup> import { provide } from &#39;vue&#39;; provide(&#39;theme&#39;, &#39;dark&#39;); </script> <!-- 后代组件 --> <script setup> import { inject } from &#39;vue&#39;; const theme = inject(&#39;theme&#39;, &#39;light&#39;); // 默认 &#39;light&#39; </script> ``` 适用于多层嵌套组件共享数据。 --- #### 四、兄弟组件 1. **事件总线(mitt)** Vue3 移除了内置事件总线,推荐使用第三方库 `mitt`: ```javascript // eventBus.js import mitt from &#39;mitt&#39;; export const emitter = mitt(); // 组件 A(发送事件) emitter.emit(&#39;message&#39;, &#39;Hello&#39;); // 组件 B(监听事件) emitter.on(&#39;message&#39;, (msg) => console.log(msg)); ``` 适用于轻量级通信场景[^1]。 2. **状态管理(Pinia/Vuex)** 全局状态管理适合复杂应用: ```javascript // store.js (Pinia) import { defineStore } from &#39;pinia&#39;; export const useStore = defineStore(&#39;main&#39;, { state: () => ({ count: 0 }), actions: { increment() { this.count++; } } }); ``` 组件中通过 `useStore()` 访问状态。 --- #### 五、expose / ref 暴露子组件方法 子组件通过 `defineExpose` 暴露特定方法: ```vue <!-- 子组件 Child.vue --> <script setup> const reset = () => { /*...*/ }; defineExpose({ reset }); </script> <!-- 父组件 --> <template> <Child ref="childRef" /> </template> <script setup> import { ref } from &#39;vue&#39;; const childRef = ref(); childRef.value.reset(); // 调用子组件方法 </script> ``` 用于父组件直接操作子组件。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值