开篇
这就接着昨天的内容再来玩一玩非父子关系!🤪🤪🤪
通过中间组件传递
<div id="app">
{{message}}
<component-a></component-a>
</div>
var bus = new Vue();
Vue.component('component-a', {
template: '<button @click="handleEvent">传递事件按钮</button>',
methods: {
handleEvent: function(){
bus.$emit('on-message', '来自组件component-a的内容')
}
},
});
var app = new Vue({
el: '#app',
data: {
message: ''
},
mounted: function(){
var _this = this;
// 初始化,监听来自bus实例的事件
bus.$on('on-message', function(msg){
_this.message = msg;
})
}
})
点击:
分析
这种很适合用在用户登录信息处理,只需要初始化时让bus获取一次即可,这样在任何组件中都可以使用了
父链
<div id="app">
{{message}}
<component-a></component-a>
</div>
<script>
var bus = new Vue();
Vue.component('component-a', {
template: '<button @click="handleEvent">点我试试通过父链修改数据</button>',
methods: {
handleEvent: function(){
this.$parent.message = '我是来自component-a的内容噢!'
}
},
});
var app = new Vue({
el: '#app',
data: {
message: ''
}
})
</script>
点击:
这个还比较好理解一点,不是通过中间组件传递,这个不分析啦
但是这里要插入一点:
那就是这种方法在实际的业务中,子组件应该尽可能避免依赖父组件的数据,更不应该去主动的修改它,因为这样会使得父子组件紧耦合😉一般情况下,只有自己的组件能修改它的状态,父子组件最好还是通过props和$emit()来通信😎
子组件索引
当子组件很多的时候,通过循环索引找到对应的组件是不现实的,尤其是组件动态渲染的时候,它们的序列又是不确定的,这里我们使用组件索引的方法,也就是——ref
<div id="app">
<button @click="handleRef">通过ref获取子组件</button>
<component-a ref="A"></component-a>
<component-b ref="B"></component-b>
</div>
<script>
Vue.component('component-a', {
template: '<div>这里是子组件1</div>',
data: function(){
return {
message: '子组件1内容'
}
}
});
Vue.component('component-b', {
template: '<div>这里是子组件2</div>',
data: function(){
return {
message: '子组件2内容'
}
}
});
var app = new Vue({
el: '#app',
data: {
message: ''
},
methods: {
handleRef: function(){
var msg = this.$refs.A.message;
console.log(msg);
}
},
})
在父组件中,子组件标签使用ref指定一个名称,并在父组件中通过this.$refs来访问指定名称的子组件,这个也比较简单,不做画图分析啦
这里再插播一点:
$refs只有在组件渲染完成后才填充,并且它是非响应式的,他仅仅作为一个直接访问子组件的应急方案,应当避免使用这种方式 😃