Vuejs 父子组件间的访问方式

2020-03-04 0 By admin

有时候我们需要父组件直接访问子组件;子组件直接访问父组件;或者是子组件访问根组件。
父组件访问子组件:使用$children 和 $refs 关键词。
子组件访问父组件:使用$parent 关键词。

一、父组件访问子组件

我们先来看下$children的访问;this.$children是一个数组类型,它包含所有子组件对象。
我们这里通过一个遍历,取出所有子组件的message状态。

1.1、$children的缺陷

通过$children访问子组件时,结果是一个数组类型,如果访问其中的子组件则必须通过索引值。
但是当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至索引值还可能会发生变化。

1.2、解决方法

如果我们想明确获取其中一个特定的组件,这个时候就可以使用 $refs 关键词。
$refs的使用:
$refs和ref指令通常是一起使用的。
首先,我们在父组件的作用范围内,引用子组件时使用ref对子组件绑定特定的ID。
其次,在父组件中,通过this.$refs.ID访问到特定的组件了。

<div id="app"> 
   <h4>VUE实例作用范围内</h4>
  <cpn1 ref="aaa"></cpn1>
  <cpn2 ref="bbb"></cpn2>
  <div ref="ccc"></div>
</div>

<template id="child-cpn1">
  <div></div>
</template>
<template id="child-cpn2">
  <div></div>
</template>

<script src="../js/vue.js"></script>
<script>
//第一个组件
const cpn1 = Vue.extend({
	template: '#child-cpn1',
	data() {
		return {
			message: '哈哈哈'
		}
	}
})
//第二个组件
const cpn2 = Vue.extend({
	template: '#child-cpn2',
	data() {
		return {
			message: '呵呵呵'
		}
	}
})
//VUE实例
const app = new Vue({
	el: '#app',
	components: {
		'cpn1': cpn1,
		'cpn2': cpn2
	},
	mounted() {
		console.log(this.$refs.aaa);
		console.log(this.$refs.aaa.$el);
		console.log(this.$refs.bbb);
		console.log(this.$refs.ccc);
	}
})
</script>

二、子组件访问父组件

如果我们想在子组件中直接访问父组件,可以通过$parent关键词。

注意事项

尽管在Vue开发中,允许通过$parent来访问父组件,但是在真实开发中尽量不要这样做。
子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了。如果我们将子组件放在另外一个组件之内,很可能该组件的父组件没有对应的属性,往往会引起问题。
另外,更不要做的是通过$parent直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护。

<div id="app">
  <cpn1 ref="aaa"></cpn1>
  <cpn2 ref="bbb"></cpn2>
  <div ref="ccc"></div>
</div>

<template id="child-cpn1">
  <div>cpn1内容</div>
</template>
<template id="child-cpn2">
  <div>cpn2内容</div>
</template>

<script src="../js/vue.js"></script>
<script>
const cpn1 = Vue.extend({
template: '#child-cpn1',
data() {
	return {
		message: '哈哈哈'
	}
}
})

const cpn2 = Vue.extend({
template: '#child-cpn2',
data() {
	return {
		message: '呵呵呵'
	}
},
mounted() {
   console.log(this.$parent.message + '------');
  }
})

const app = new Vue({
el: '#app',
components: {
	'cpn1': cpn1,
	'cpn2': cpn2
},
data: {
	message: '滴滴滴滴'
},
mounted() {
	console.log(this.$refs.aaa);
	console.log(this.$refs.aaa.$el);
	console.log(this.$refs.bbb);
	console.log(this.$refs.ccc);
	}
})
</script>

三、非父子组件间访问

如果是非父子组件,如果相互调用呢?
非父子组件关系包括多个层级的组件,也包括兄弟组件的关系。

3.1、在Vue1.x的时候

可以通过$dispatch和$broadcast完成。$dispatch用于向上级派发事件,$broadcast用于向下级广播事件。

3.2、但是在Vue2.x都被取消了

在Vue2.x中,有一种方案是通过中央事件总线,也就是一个中介来完成。
但是这种方案和直接使用Vuex的状态管理方案还是逊色很多。并且Vuex提供了更多好用的功能,所以这里我们暂且不讨论这种方案,后续我们专门学习Vuex的状态管理。