Vue入门—非父子组件间的数据传递(Bus)

本文讲解Vue中非父子组件间的数据传递方法,采用Bus/总线/发布订阅模式实现组件间通信,通过实例演示如何利用Vue原型上的bus属性实现数据共享。

Vue入门—非父子组件间的数据传递

前一篇文章讲了有关Vue中父子间的数据传递方式
其中我们了解到:

父组件通过属性来像子组件传值
子组件通过事件触发的方式向父组件传值

今天我们一起来学习有关非父子组件间的数据传递
首先我们来看张图
这张图里向我们展示了,在一个网页中Vue可以将其分成多个组件,组件之间也会进行数据传递。
但就上篇文章了解到的,父子组件的传递,应该是1和2/2和3 但如果1和3,3和3,2和2之间需要进行数据传递。
在这里插入图片描述
在这里我们主要讲同父组件的子组件之间的传递,如图2和2之间的数据传递。
首先我们先想一想,假设我们现在需要传递有什么方法呢?
也许你会想,我能不能先将一个2的数据通过事件触发的形式传给父组件1,然后再由父组件1通过属性传值给另一个2.
其实这种想法是没有错误的,只是这样的流程太过于麻烦。而Vue本身是一个轻量级框架,当我们在项目中遇到很多的事件,我们则需要使用其他的工具或者是设计模式。

了解到这里,我们就开始今天的学习吧,首先,创建一个基础的Vue实例,和一个子组件,同时在子组件中通过props接收父组件传来的数据。

<body>
		<div id="root">
			<child content="Dell"></child>
			<child content="De"></child>
			</div>
		
		<script>
			Vue.component('child',{
			data:function(){
					return{
						selfContent:this.content
					}
				},
				props:{
					content:String
				},
				template:'<div>{{selfContent}}</div>'
				
			})
			
			var vm = new Vue({
				el:'#root'
			})
		</script>
	</body>

因为要实现非父子组件的数据传递,所以这里我们需要实现的是下面两个组件分别点击传值。

<child content="Dell"></child>
<child content="De"></child>

传值方式又称(Bus/总线 /发布订阅模式 /观察者模式

Vue.prototype.bus = new Vue()

我们在Vue的prototype挂载了一个bus,让其指向一个Vue的实例
只要我们之后去调用Vue 或者是创建组件的时候,每一个组件上都有bus这个属性(因为每一个组件,Vue实例都是通过Vue的类来创建的,而此时我们在这个类上挂载了bus,它都指向同一个Vue实例)

为了实现点击改变值,我们绑定点击事件

template:'<div @click="handleClick">{{selfContent}}</div>',
				methods:{
					handleClick:function(){
						this.bus.$emit('change',this.selfContent)
					}
				},

实例上挂载了bus属性,而bus是一个Vue实例,因此具有$emit 方法,监听change事件,同时这个事件携带了数据this.selfContent

一个子组件触发事件,那么其他子组件需要监听数据,这里我们使用到声明周期钩子mounted(这个组件被挂载的时候,会自动执行的函数)

mounted:function(){
					var this_=this
					this.bus.$on('change',function(msg){
						this_.selfContent = msg
					})

实例上挂载了bus属性,而bus是一个Vue实例,因此具有$on方法,监听change事件,同时这个事件携带了带参函数

好了,写到这,我们就可以实现两个子组件之间的数据传递。
大家可以尝试一下
如果有错,欢迎指正

代码很短,理解便好。

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>非父子组件传值关系(Bus 总线 发布订阅模式 观察者模式)</title>
		<script src="./vue.js"></script>
	</head>
	<body>
		<div id="root">
			<child content="1"></child>
			<child content="2"></child>
			</div>
		
		<script>
			Vue.prototype.bus = new Vue()
			
			Vue.component('child',{
				data:function(){
					return{
						selfContent:this.content
					}
				},
				props:{
					content:String
				},
				template:'<div @click="handleClick">{{selfContent}}</div>',
				methods:{
					handleClick:function(){
						this.bus.$emit('change',this.selfContent)
					}
				},
				mounted:function(){
					var this_=this
					this.bus.$on('change',function(msg){
						this_.selfContent = msg
					})
				}
				
			})
			
			var vm = new Vue({
				el:'#root'
			})
		</script>
	</body>
</html>

下次再见哦。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值