vue组件之间的通信

本文详细介绍了Vue组件间的通信机制,包括父子组件通信的prop、event、style/class属性、attribute、native修饰符、sync修饰符及ref的使用,以及跨组件通信的Provide/Inject、Vuex和Router方法。通过实例解析了各种通信方式的实现和应用场景。
摘要由CSDN通过智能技术生成

1、vue组件的目的

1、降低整体的复杂度(粗粒度降解成细粒度),提高代码的可读性和可维护性,
2、提高局部代码的可复用性
当整体被拆解成了一块一块的组建以后,所有的组件都是独立存在的,如果需要关联起来,就需要用到组建中的相互传值,相互传值分为两种
1、父子组件之间的传值
2、跨组件之间的传值

2、父子组件之间通信

大部分的通讯方式都是父子组件之间的传值

(1)prop 与 event

父组件传递属性给子组件,子组件通过props对象来声明父组件传过来的值,例如

// 父组件中
<template>
	<div>
		<!-- 使用子组件 -->
		<son num="1"></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son}
}
</script>
// 子组件中
<template>
	<div>
		<!-- 使用父组件传递过来的值 -->
		<h1>{{ num }}</h1>
	</div>
</template>
<script>
export default {
	//声明父组件传过来的值
	props: [ 'num' ]
}
</script>

(2)style,class属性

如果父组件向子组件传递styleclass属性,那么这两个属性,就会合并到子组件的根元素中,使用的范围比较窄,主要的目的就是父组件给子组件传递样式

// 父组件中
<template>
	<div>
		<!-- 使用子组件,并在子组件上设置了class, style属性 -->
		<son style="color: #fff" class="father"></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son}
}
</script>
// 最后子组件中就变成了以下的样子
<template>
	<div class="father" style="color: #fff">
		<h1>我是一个啥都没有的子组件</h1>
	</div>
</template>
<script>
export default {}
</script>

如果子组件中已经有了class和style这两个属性

// 子组件中
<template>
	<div class="son" style="font-size: 16px">
		<h1>我是一个啥都没有的子组件</h1>
	</div>
</template>
<script>
export default {}
</script>

那么就会进行合并

// 最后子组件中就变成了以下的样子
<template>
	<div class="son father" style="font-size: 16px; color: #fff">
		<h1>我是一个啥都没有的子组件</h1>
	</div>
</template>
<script>
export default {}
</script>

(3)attribute

如果父组件向子组件传递了属性,但是子组件中并没有声明这个属性,那么这些没有被声明的属性就是attribute,这些没有被子组件声明的属性就会被添加到子组件的根元素上,例如

// 父组件中
<template>
	<div>
		<!-- 使用子组件,并在子组件上传递 nameA, nameB两个属性 -->
		<son nameA="A" nameB="B"></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son}
}
</script>
// 子组件中
<template>
	<div >
		<h1>父组件给我传递了两个属性,但是我并没有在props中声明</h1>
	</div>
</template>
<script>
export default {}
</script>

最后的渲染结果为

// 子组件中
<template>
	<!-- nameA, nameB两个属性就会被添加到根元素上 -->
	<div nameA="A" nameB="B">
		<h1>父组件给我传递了两个属性,但是我并没有在props中声明</h1>
	</div>
</template>
<script>
export default {}
</script>

在子组件中,可以通过this.$attrs这个对象,获取从父组件中传过来但是子组件没有声明的值。注意:style和class除外

// 子组件中
<template>
	<!-- nameA, nameB两个属性就会被添加到根元素上 -->
	<div nameA="A" nameB="B">
		<h1>父组件给我传递了两个属性,但是我并没有在props中声明</h1>
	</div>
</template>
<script>
export default {
	created() {
		// 通过this.$attrs,得到 nameA, nameB 这两个属性和属性值
		console.log(this.$attrs)
	}
}
</script>

注意:子组件可以通过inheritAttrs: false,将attribute禁止添加到根元素上面,但是不影响this.$attrs中的获取

(4)natvie修饰符

父组件可以通过native修饰符,将事件注册到子组件的根元素上,让子元素去使用。例如

// 子组件中
<template>
	<div >
		<h1>我是子元素,我很干净,啥也没有,事件就更没有了</h1>
	</div>
</template>
<script>
export default {}
</script>
// 父组件中
<template>
	<div>
		<!-- 在子组件上注册一个click事件,
		     并使用.natvie修饰,这样子组件
		     就可以使用了 -->
		<son @click.natvie="sonClick"></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son},
	methods: {
		sonClick() {
			console.log('这是父组件在子组件上注册的点击方法!')
		}
}
</script>

(5)sync修饰符

sync修饰符是一个语法糖,用于双向数据绑定,一个组件可以多个属性用.sync修饰符,可以同时"双向绑定多个“prop”,v-model只能对一个数据进行双向数据绑定。注意:vue3将v-model和sync修饰符合并了
不使用sync修饰 例如

// 子组件中
<template>
	<div>
		<h1>{{ num1 }}</h1>
		<button @click="$emit('update:num1', num1 - 1)"></button>
		<button @click="$emit('update:num1', num1 + 1)"></button>
		<h1>{{ num2 }}</h1>
		<button @click="$emit('update:num2', num2 - 1)"></button>
		<button @click="$emit('update:num2', num2 + 1)"></button>
	</div>
</template>
<script>
export default {
	props: ['num1', 'num2']
}
</script>
// 父组件中
<template>
	<div>
		<!-- 如果触发num1的时候,就赋值num1 -->
		<!-- 如果触发num2的时候,就赋值num2 -->
		<son :num1="n1" 
			 :num2="n2" 
			 @update:num1="n1 = $event"
			 @update:num2="n2 = $event"
			 ></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son}data() {
		return: {
			n1: 1,
			n2: 2
		}
	}
}
</script>

使用sync修饰符可以简化成以下写法:

// 父组件中
<template>
	<div>
		<!-- 使用sync修饰符可以简化成一下写法 -->
		<son :num1.sync="n1" 
			 :num2.sync="n2" 
			 ></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son}data() {
		return: {
			n1: 1,
			n2: 2
		}
	}
}
</script>

(6)ref

父组件可以通过ref获取到子组件的实例信息,例如
// 父组件中
<template>
	<div>
		<!-- 使用ref获取子组件实例 -->
		<son ref="sonRef"></son>
	</div>
</template>
<script>
import son './son'
export default {
	// 注册子组件
	components: {son}mounted() {
		// 获取子组件的实例信息,可以调用子组件的方法或者属性
		console.log(this.$refs.sonRef)
	}
}
</script>

(7)$listeners

子组件可以通过$listeners,获取父组件传递过来的所有事件处理函数。

3、跨组件通信

(1)Provide 与 Inject

Provide、Inject是vue官方提供的,可以跨组件应用,但是兄弟组件不能使用该方法,父子,祖先组件是可以使用的,一般应用于一些公共的组件库。

官方文档(详细): https://cn.vuejs.org/v2/api/?#provide-inject

(2)vuex

大型项目可以使用vuex做数据之间的传输和共享

(3)router

组件改变了地址栏,可以将地址栏作为数据传输的路径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值