Vue中组件之间传值的三种常用方法

本文详细介绍了Vue.js中不同组件间通信的多种方式,包括父子组件间的prop和事件通信、同级组件间通过公共实例文件的传值方法,以及如何使用Vuex进行状态管理。

在使用vue的过程中免不了要组件之间传值,那么这里就说一说传值的几种方法和怎么使用
先来看一张图
引用官网的一句话:父子组件的关系可以总结为 prop 向下传递,事件向上传递。父组件通过 prop 给子组件下发数据,子组件通过事件给父组件发送消息,如下图所示:

一.父组件向子组件传值
来,先上代码
父组件:

<template>
  <div>
    父组件:
    <input type="text" v-model="name">		//v-model绑定
    <br>
    <br>
    <!-- 引入子组件 -->
    <child :inputName="name"></child>
  </div>
</template>
<script>
	  import child from './child'		//引入
	  export default {
	    components: {
	      child									
	    },
	    data () {
	      return {
	        name: ''
	      }
	    }
	  }
</script>

子组件:

<template>
  <div>
    子组件:
    <span>{{inputName}}</span>
  </div>
</template>
<script>
  export default {
    // 接受父组件的值
    props: {
      inputName: String,
      required: true
    }
  }
</script>

二.子组件向父组件传值

在子组件中创建一个按钮,并绑定一个点击事件

<template>
	<div>
		<li v-for="(item,index) in arr" >
			<p>{{item}}</p>
			<button @click="chuanzhi(index)">删除</button>
		</li>	
	</div>
</template>

在js的methods中定义这个事件函数中使用$emit来触发一个事件并传递一个参数

chuanzhi(index){
	this.$emit("jieshou",index)
}

在父组件中v-on监听这个事件(jieshou)并添加一个响应事件的方法

<template>
  <div class="hello">
	<router-link to="/6">426636</router-link>
    	<h1>{{ msg }}</h1>
   	<input type="text" v-model="txt">
	<button @click="dianji">留言</button>
	<Show v-bind:arr="arr" v-on:jieshou="xuanran"></Show>
  </div>
</template>

js中

xuanran(data){
	console.log(data)
	this.arr.splice(data,1)	
}

三.同级组件之间的传值(创建一个公共js文件)
这里我们先说一下如何创建一个公共文件去传值,下一篇会说到如何使用Vuex状态管理器来建立一个仓库进行组件之间的传值。

非父子组件之间传值,需要定义个公共的公共实例文件bus.js,作为中间仓库来传值,不然路由组件之间达不到传值的效果。
1、在工程src目录下新建一个Pub.js文件
Pub.js
	import Vue from "vue"
	export default new Vue()
2、在各组件中引入Pub.js文件
	import Pub from "../Pub.js"
3、在A组件中通过$emit调用自定义函数并且传参
	Pub.$emit('namefn',"str1","str2",……)
4、在B组件中通过$on响应事件并接受参数
	Pub.$on('namefn',(str1,str2,……) =>{
		console.log(str1+"就是A组件中定义的数据")
	})

示例代码:
公共bus.js

//bus.js
import Vue from 'vue'		//移入Vue
export default new Vue()		//暴露给Vue这个全局对象

组件A中

<template>
  <div>
    A组件:
    <span>{{elementValue}}</span>
    <input type="button" value="点击触发" @click="elementByValue">
  </div>
</template>
<script>
  // 引入公共的bug,来做为中间传达的工具
  import Bus from './bus.js'
  export default {
    data () {
      return {
        elementValue: 4
      }
    },
    methods: {
      elementByValue: function () {
        Bus.$emit('val', this.elementValue)
      }
    }
  }
</script>

组件B中:

<template>
  <div>
    B组件:
    <input type="button" value="点击触发" @click="getData">
    <span>{{name}}</span>
  </div>
</template>
<script>
  import Bus from './bus.js'
  export default {
    data () {
      return {
        name: 0
      }
    },
    mounted: function () {
      var vm = this
      // 用$on事件来接收参数
      Bus.$on('val', (data) => {
        console.log(data)
        vm.name = data
      })
    },
    methods: {
      getData: function () {
        this.name++
      }
    }
  }
</script>
<think>好的,用户想了解在Vue中如何实现兄弟组件之间方法。我需要先回忆一下Vue3中兄弟组件通信的几种方式。根据之前提供的引用,主要有两种方法:使用Mitt插件或者利用provide和inject的响应式API。外,还有通过事件总线(Bus)的方式,不过这在Vue3中可能需要自己实现,或者使用第三方库如Mitt。 首先,用户可能已经了解过Vue2中的事件总线,但在Vue3中,官方移除了$on等方法,所以需要替代方案。Mitt是一个轻量的事件总线库,适用于Vue3。步骤包括安装Mitt,创建事件总线实例,然后在兄弟组件中分别使用emit和on来触发和监听事件。需要确保两个组件引用的是同一个事件总线实例,通常会在全局注册。 一种方法是使用provide和inject配合响应式数据。父组件提供一个响应式的对象,兄弟组件通过inject获取这个对象,并修改其中的数据。这样,当数据变化时,所有注入该数据的组件都会更新。需要注意的是,Vue3的provide/inject默认不是响应式的,所以必须使用ref或reactive来包装数据。 用户可能关心哪种方法更推荐。Mitt适合事件驱动的通信,而provide/inject适合共享状态。如果项目已经使用Pinia或Vuex,可能更推荐状态管理库来处理兄弟组件通信,但用户的问题没有提到这些,所以暂时不引入。 外,引用中的示例代码显示在子组件中使用$emit,但Vue3中兄弟组件不能直接通过父组件递事件,需要父组件作为中介,或者使用事件总线。所以需要区分子组件和兄弟组件的场景。 需要确保回答结构清晰,分点说明每种方法,并给出示例代码。同时,根据用户提供的引用,正确引用来源,比如Mitt方法引用[^1],事件总线引用[^3],而引用[^2]中的例子可能不适用于兄弟组件,因为$emit需要父组件监听,所以可能需要指出那种方式适用于父子而非兄弟,避免混淆。 最后,生成相关问题,比如性能比较、其他方法Vuex,或者具体使用场景,帮助用户深入理解。</think>在 Vue3 中实现兄弟组件通信的常用方法主要有以下两种方式,均支持响应式数据递: --- ### 一、使用 Mitt 事件总线(推荐) 1. **安装 Mitt 插件** ```bash npm install mitt ``` 2. **创建全局事件总线** ```javascript // src/utils/bus.js import mitt from 'mitt' export default mitt() ``` 3. **组件 A 发送事件** ```vue <script setup> import bus from '@/utils/bus' const sendData = () => { bus.emit('customEvent', { value: '数据内容' }) } </script> ``` 4. **组件 B 接收事件** ```vue <script setup> import bus from '@/utils/bus' import { onMounted } from 'vue' onMounted(() => { bus.on('customEvent', (data) => { console.log('接收数据:', data.value) // 输出:数据内容 }) }) </script> ``` **特点**:解耦组件关系,适合跨层级通信[^1][^3] --- ### 二、使用 provide/inject + 响应式状态 1. **父组件提供共享状态** ```vue <script setup> import { provide, reactive } from 'vue' const sharedState = reactive({ message: '' }) provide('sharedKey', sharedState) </script> <template> <ComponentA /> <ComponentB /> </template> ``` 2. **兄弟组件修改状态** ```vue <!-- ComponentA --> <script setup> import { inject } from 'vue' const state = inject('sharedKey') state.message = '来自A的数据' </script> ``` 3. **兄弟组件读取状态** ```vue <!-- ComponentB --> <script setup> import { inject } from 'vue' const state = inject('sharedKey') console.log(state.message) // 输出:来自A的数据 </script> ``` **特点**:适合需要持久化共享的状态[^1] --- ### 性能对比 | 方法 | 适用场景 | 数据流向 | |-----------|----------------------|------------| | Mitt | 瞬时事件通信(表单提交/通知) | 单向/双向 | | provide | 需要长期维护的共享状态(主题/配置) | 集中式状态管理 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值