上两篇提到父子组件间的通讯可以通过数据传递的方式,通过props和$emit。父子组件之间还可以相互引用,父组件拿到子组件的实例,进而调用子组件的属性和方法等。反之,子组件拿到父组件的实例也是一样。先看下父组件如何引用子组件,两种方式$children和$refs。
$children方式
$children返回的是子组件的数组。可以通过下标获取子组件实例,进而引用子组件的属性和方法。如下:
<div id="app">
<mycpn></mycpn>
<button @click="btnclick">点击</button>
</div>
<script src="../js/vue.js"></script>
<template id="cpn">
<div>
<h2>{{title}}</h2>
</div>
</template>
<script>
//相当于vue的子组件
const mycpn={
template:'#cpn',
data(){
return {
title: '我是子组件'
}
},
methods:{
showMessage(){
console.log('子组件方法!');
}
}
}
//创建并注册组件
Vue.component('mycpn',mycpn);
//vue相当于父组件
const vue = new Vue({
el:"#app",
components:{
mycpn:mycpn
},
methods:{
btnclick(){
//$children方式,返回子组件数组
//引用子组件的方法
this.$children[0].showMessage();
//引用子组件的属性
console.log(this.$children[0].title);
}
}
});
</script>
效果如下:
$refs方式
$children是通过下标的方式获取组件实例,如果组件的个数或者顺序发生改变,引用的下标也要发生改变,因此,这种方式有弊端。
$refs方式通过给组件添加ref属性,通过ref属性名称名称获取组件,不必关心子组件的顺序或者数量的改变,只要子组件ref属性名称不变就可以找到。
如下所示:
<div id="app">
<mycpn ref="a"></mycpn>
<mycpn ref="b"></mycpn>
<mycpn ref="c"></mycpn>
<button @click="btnclick">点击</button>
</div>
<script src="../js/vue.js"></script>
<template id="cpn">
<div>
<h2>{{title}}</h2>
</div>
</template>
<script>
//相当于vue的子组件
const mycpn={
template:'#cpn',
data(){
return {
title: '我是子组件'
}
},
methods:{
showMessage(){
console.log('子组件方法!');
}
}
}
//创建并注册组件
Vue.component('mycpn',mycpn);
//vue相当于父组件
const vue = new Vue({
el:"#app",
components:{
mycpn:mycpn
},
methods:{
btnclick(){
//$children方式,返回子组件数组
//引用子组件的方法
//this.$children[0].showMessage();
//引用子组件的属性
//console.log(this.$children[0].title);
//$refs方式,默认返回空
this.$refs['a'].showMessage();
console.log(this.$refs['a'].title);
this.$refs['b'].showMessage();
console.log(this.$refs['b'].title);
}
}
});
</script>
效果如下: