Vue组件之间的传值

本文详细介绍了Vue.js中组件间的通信方式,包括父子通信(属性传递与事件触发)、子传父(事件冒泡与回调函数)以及兄弟组件间通信的总线(bus)模式。通过实例解析了如何利用props、$emit和$on实现不同组件间的值传递,强调了在实际开发中合理选择通信方式的重要性。
摘要由CSDN通过智能技术生成

首先Vue组件之间的传值有两种

父子通信和非父子通信(bus通信)

1.父子通信

父传子:
首先你得传一个值过去吧

<body>
		<div id="app">
			<input type="button" @click="handlclik" value="点击" />
			<navbar :mytitle="title" v-for="title in list" ></navbar>
		</div>
	</body>

	<script>
		Vue.component('navbar', {
			template: `<div>{{mytitle}}</div>`,
			props: ["mytitle"],
			data() {
				return {
					data: '这是一段组件插入',
				}
			},
			methods: {

			}
		})
		var vue = new Vue({
			el: '#app',
			data: {
				list: ['首页', '列表', '详情'],
			},
			methods: {
				handlclik() {

				}
			}
		})
	</script>

父传子类似于传过去一个键值对(key:value) 比如上述导航栏组件中,父传子的是一个mytitle:title 键值对,用了一个v-for循环取出里面的值:首页,列表,详情等,然后传给子组件.

父亲传过去了,子组件当然要接收了 ,于是子组件定义了props属性数组来接收父亲传过来的对象,类似于你爸给你打钱,你得用微信或银行卡来接收.
然后就能显示了在这里插入图片描述
当然你也可以传很多东西,只是要增加键值对的数量
比如

<navbar :mytitle="title" mymsg="多来一个字符串!" v-for="title in list" ></navbar>
//然后相应的子组件要接收他
props:["mytitle","mymsg"]

此方法只适用于传 字符串! 当然了,你也可以在子组件中进行强转,但未免太过麻烦,所以我们是能直接接收来自父组件的类似于boolean值或者number值的
只要更改一下props格式:

props: {
		mytitle:String,
		mymsg:Number,
		myboolean:Boolean,
},
//相应的父组件
<navbar :mytitle="title" :mymsg='123' :myboolean='true' 
 v-for="title in list" ></navbar>

显示的为在这里插入图片描述
还有一种写法

props: {
    mytitle: {
      type: String,
      default: ''
    }
  }

这里就有一个type类型,表示我这个mytitle期望获得一个String类型的值,如果是别的就会报错,default 为空,表示默认为空值,有时候我们要传给子组件一个值,只是暂时我们还没有传,但我们已经写好了这种通信方式,只是没有传过去而已,这时我们就有一个默认值default,一旦我们传过去一个值,就会覆盖这个default默认值

2.子传父
记住子传父是通过事件触发的,也可以把你给你爸打钱理解为一个事件!
首先你得你孩子你得银行卡吧

<navbar  @bank-card="reciveMoney" ></navbar>

然后孩子用事件就得打钱吧

Vue.component('navbar', {
			template: `<div><button @click="handleClick">给爸爸打钱!</button></div> `,
			data() {
				return {
					money: 10000,
				}
			},
			methods: {
				handleClick(){
					this.$emit("bank-card",this.money);
				}
			}
		})

这里得this.$emit就是打钱得意思emit有发射的意思,理解为打钱就行了
,然后bank-card就是你要打钱的银行卡,this.money就是你要打的钱
打完了父亲得接收吧

methods: {
				reciveMoney(childMoney) {
					console.log(childMoney)
				}
			}

接收完了就ok了,在这里插入图片描述

还有一种方式,通过ref

介绍一下ref:ef 被用来给DOM元素或子组件注册引用信息。引用信息会根据父组件的 $refs 对象进行注册。如果在普通的DOM元素上使用,引用信息就是元素; 如果用在子组件上,引用信息就是组件实例
注意:只要想要在Vue中直接操作DOM元素,就必须用ref属性进行注册

例如:

<body>
		<div id="app">
			<input type="text" ref='mytext' />
			<div ref='mydiv'></div>
			<button @click="handleClick">点击获取dom节点</button>
			<navbar></navbar>
		</div>
	</body>

	<script>
		Vue.component('navbar', {
			template: `<div></div>`,
			data() {
				return {
					money: 10000,
				}
			},
			methods: {
				
			}
		})


		new Vue({
			el: '#app',
			data: {
				list: ['首页', '列表', '详情'],
				money: '',
			},
			methods: {
				handleClick() {
					console.log(this.$refs)
				}
			}
		})
	</script>

在这里插入图片描述
点击获取dom节点,控制台就会打印:
在这里插入图片描述
看到这里大家已经大概明白了
比如我想获得输入框的内容
改一下代码:

console.log(this.$refs.mytext.value)

打印的就会是在这里插入图片描述
这样呢,如果把他加在组件中呢?
改一下代码

<navbar ref='mynavbar'></navbar>


console.log(this.$refs.mynavbar)

打印的:

在这里插入图片描述
是不是直接就获得了money的值了呢
拿来用就可以直接

this.$refs.mynavbar.money

注意:ref方法可以做到,但是在开发中不推荐使用,因为他不经过子组件的同意直接拿到子组件的值修改使用,万一将来数据出错,由于不知道数据是谁修改的,将极大的增加纠错难度,不推荐使用!

3.兄弟组件传值(子组件传子组件)

1.找个相同的父组件,通过父组件作为中间人传值,方法同上
2.bus通信
中间人传值可以解决一些简单的问题,但是如果子组件嵌套子组件呢?比如你的孩子又有了一个孩子,你孩子的孩子还有了一个孩子,总不能一个个找父亲,一个个传回来吧?
这时就可以用bus通信,bus:中央控制总线
通过中央控制总线来进行各个组件的传值
首先定义一个bus,很简单,一个空的vue,名字为bus(其实名字你随意取),

var bus = new Vue()

其实这个就类似于微信的发布-订阅模式,或者有点像java的观察者模式,
用bus.$on来监听,bus. $emit来发布

<body>
		<div id="app">
			<child1></child1>
			<child2></child2>
		</div>
	</body>

	<script>
		var bus = new Vue()
		
		Vue.component('child1', {
			template: `<div><button @click='emit'>发布</button></div>`,
			data() {
				return {
					msg1:'震惊!zs竟然干出这种事...'
				}
			},
			methods: {
				emit(){
					bus.$emit('wechat',this.msg1);
				}
			}
		})
		
		Vue.component('child2', {
			template: `<div>{{msg2}}</div>`,
			data() {
				return {
					msg2:''
				}
			},
			mounted() {
				bus.$on("wechat",(data)=>{
					console.log(data)
					this.msg2=data
				})
			}
		})
		


		new Vue({
			el: '#app',
			data: {
				list: ['首页', '列表', '详情'],
				money: '',
			},
			methods: {
				handleClick() {
					console.log(this.$refs.mynavbar.money)
				}
			}
		})
	</script>

也类似于中间人,不过这个中间人是bus,通过bus.$on和bus. $emit同时监听wechat,发送和接收消息,也是通过方法接收发送的,mounted方法是vue生命周期创建时自动调用的一个方法,(data)=>{}是方法的简写模式,省略了方法名,data就是传来的msg1,这样就实现了子组件子组件的传值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值