有时候我们需要父组件直接访问子组件;子组件直接访问父组件;或者是子组件访问根组件。
父组件访问子组件:使用$children 和 $refs 关键词。
子组件访问父组件:使用$parent 关键词。
一、父组件访问子组件
我们先来看下$children的访问;this.$children是一个数组类型,它包含所有子组件对象。
我们这里通过一个遍历,取出所有子组件的message状态。
1.1、$children的缺陷
通过$children访问子组件时,结果是一个数组类型,如果访问其中的子组件则必须通过索引值。
但是当子组件过多,我们需要拿到其中一个时,往往不能确定它的索引值,甚至索引值还可能会发生变化。
1.2、解决方法
如果我们想明确获取其中一个特定的组件,这个时候就可以使用 $refs 关键词。
$refs的使用:
$refs和ref指令通常是一起使用的。
首先,我们在父组件的作用范围内,引用子组件时使用ref对子组件绑定特定的ID。
其次,在父组件中,通过this.$refs.ID访问到特定的组件了。
VUE实例作用范围内
//第一个组件
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);
}
})
二、子组件访问父组件
如果我们想在子组件中直接访问父组件,可以通过$parent关键词。
注意事项
尽管在Vue开发中,允许通过$parent来访问父组件,但是在真实开发中尽量不要这样做。
子组件应该尽量避免直接访问父组件的数据,因为这样耦合度太高了。如果我们将子组件放在另外一个组件之内,很可能该组件的父组件没有对应的属性,往往会引起问题。
另外,更不要做的是通过$parent直接修改父组件的状态,那么父组件中的状态将变得飘忽不定,很不利于我的调试和维护。
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);
}
})
三、非父子组件间访问
如果是非父子组件,如果相互调用呢?
非父子组件关系包括多个层级的组件,也包括兄弟组件的关系。
3.1、在Vue1.x的时候
可以通过$dispatch和$broadcast完成。$dispatch用于向上级派发事件,$broadcast用于向下级广播事件。
3.2、但是在Vue2.x都被取消了
在Vue2.x中,有一种方案是通过中央事件总线,也就是一个中介来完成。
但是这种方案和直接使用Vuex的状态管理方案还是逊色很多。并且Vuex提供了更多好用的功能,所以这里我们暂且不讨论这种方案,后续我们专门学习Vuex的状态管理。