总结:VUE组件间的通信

总结:Vue组件间的通信

一、父子组件

1、父组件传值属性传参,子组件props接收
例:
父组件:

<div>
	<child val="val"></child>
</div>

子组件:

<script>
export default {
	props: {
		val: {
			type: String,
			default: ''
		}
	}
}
</script>

2、$attrs接收父组件传值,但没有在子组件props声明
例:
父组件:

<div>
	<child val="val"></child>
</div>

子组件:

<div>
	<div v-bind="$attrs" :val="$attrs.val"></div>
</div>

注意v-bind="$attrs"此种方式$attrs会以键值对的形式默认展开在当前节点,但是当前实例的根节点会继承$attrs展开的属性
解决:

export default {
	inheritAttrs: false
}

3、$refs父组件获取子组件实例从而修改子组件的数据
例:
父组件:

<div>
	<child ref="child"></child>
</div>
export default {
	mounted () {
		this.$refs.child.val = '111111111111'
	}
}

子组件:

export default {
	data() {
		return {
			val: '1'
		}
	}
}

4、$children父组件获取子组件实例从而修改子组件的数据

父组件:

<div>
	<child></child>
</div>
export default {
	mounted () {
		this.$children[0].val = '111111111111'
	}
}

子组件:

export default {
	data() {
		return {
			val: '1'
		}
	}
}

注意:此种方式不推荐使用,因为父组件内可能会有很多子组件,并且子组件有可能是为异步组件,所以父组件内各个子组件实例的顺序即index下标并不一定是固定的,所以有可能会导致获取改变失败。


5、$emit子组件派发事件,父组件内的子组件监听事件(事件由派发者监听)
子组件:

<div>
	<button @click="clickBtn">点击派发事件</button>
</div>
export default {
	methods () {
		clickBtn () {
			this.$emit('myClick', '子组件内部点击触发')
		}
	}
}

父组件:

<div>
	<child @myClick="myClick"></child>
</div>
export default {
	methods () {
		myClick (val) {
			console.log(val) // 子组件内部点击触发
		}
	}
}

注意: 常用此种方式进行子组件向父组件的通信


二、兄弟组件之间的通信

注意:兄弟组件间的通信通常会使用第三方传递,即兄弟组件共同的父辈或者祖辈来传递数据


父辈组件:$parent || $root

<div>
	<child1></child1>
	<child2></child2>
</div>

子组件1:子组件1点击触发通讯给子组件2

<div>
	<div @click="say2"></div>
</div>
export default {
	methods () {
		say2 () {
			this.$parent.$emit('receice1')
		}
	}
}

子组件2:子组件2内部监听子组件1触发的通信

export default {
	mounted () {
		this.$parent.$on('receive1', () => {
			console.log('我接收到了来自兄弟的通信')
		})
	}
}

三、祖先和后代间的通信(跨很多组件)provideinject

正常很少使用这种方式,组件开发的时候偶尔会用到


祖先节点:

export default {
	provide () {
		return {
			val: 111
		}
	}
}

后代节点:

export default {
	inject: [
		'val'
	]
}

注意:单向传递数据(由祖先-》后代)


四、任意两个组件间的通信vuex、事件总线bus

1、vuex采用最多的一种方式,不做示例
2、事件总线bus

抽离出bus

bus.js
import Vue from 'vue'
const Bus = new Vue()
export default Bus

使用bus

import Bus from './utils/bus'
Bus.$emit('busHandle')
Bus.$on('busHandle', () => {})

注意:注册的总线事件要在组件销毁时卸载,否则会多次挂载,造成触发一次但多个响应的情况

export default {
	beforeDestroy () {
        this.bus.$off('busHandle')
    }
}

模拟BUS的实现

// bus.js
class Bus {
	constructor: {
		this.classback = {} // 用来存储所有的事件
	}
	$on (name, fn) { // name:事件名形参名,fn为事件回调函数
		this.callback[name] = this.callback[name] || [] // 当name第一次被监听,则创建一个名为name的数组,用来存储所有的该name的回调函数
		this.callback[name].push(fn)
	}
	$emit (name, args) { // name、args触发回调函数传递的参数
		if (this.callback[name]) {
			this.callback[name].forEach((cb) => {
				cb(args) // 触发当前name身上绑定的所有的回调函数
			})
		}
	}
}
export default Bus

使用:引入busbus.$onbus.$emit

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值