第二种:兄弟节点之间的通信
两个兄弟节点之间的通信:child2想修改chid1中的属性plan,怎样可以实现呢?
一、中央事件总线(EventBus)
定义一个EventBus(Vue的一个实例),使用$on来进行监听,使用$emit来进行派发,用代买来演示具体的实现流程
EventBus
import Vue from 'vue'export default new Vue()父组件,其实这里就与父组件没有关系了,只是为了展示两个子组件的关系
<template> <div> {{childMsg}} <child @changeByChild="changenameHandle"/> </div></template><script>import child from '@/components/child'export default { name: 'parent', components: { child }, data () { return { childMsg: 'this is a child' } }, methods: { changenameHandle (val) { console.log(val) this.childMsg = val } }}</script><style></style>子组件child1
<template> <div id="child1-wrap" class="child1-wrap"> {{plan}} </div></template><script>import EventBus from '@/components/EventBus'export default { name: 'child1', data () { return { plan: 'I\'m going to have a move tomorrow' } }, created () { EventBus.$on('changePlanByChild2', (val) => { this.plan = val }) }}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>.child1-wrap { font-size: 30px; color: brown;}</style>子组件child2
<template> <div id="child2-wrap" class="child2-wrap"> <input type="text" @input="changePlan"> </div></template><script>import EventBus from '@/components/EventBus'export default { name: 'child2', data () { return { } }, methods: { changePlan (e) { EventBus.$emit('changePlanByChild2', e.target.value) } }}</script><style scoped>.child2-wrap { font-size: 28px; color: aqua;}</style>运行代码,在child2组件中修改input内的值,child1中的plan属性同时跟着进行了修改,通过eventbus我们实现兄弟节点之间的通信,需要指出的是:这种中央事件代理并不是vue的特有的
二、通过上child1--->父节点--->child2
如果是这种方法的话,我们由上一篇文章可以得出:在父组件中定义plan属性,使用props将plan传递到child1子组件中,在child2中使用$emit将修改操作委托到父组件中,由父组件进行修改的操作,这时候由props传递到child1中的plan随之变化,这样child2就相当于有了”修改“child2的能力,就不再进行演示了
这里我们使用另一种方式来实现,父组件来调用子组件内的方法(使用$ref)
vue提供了ref来帮助我们实现在父组件内访问或者调用子组件的属性和方法,代码演示如下
父组件
<template> <div> <child1 ref="child1"/> <child2 @changeChild1="changeChild1ByChild2"/> </div></template><script>import child1 from '@/components/child1'import child2 from '@/components/child2'export default { name: 'parent2', components: { child1, child2 }, data () { return {} }, methods: { changeChild1ByChild2 (val) { console.log(this.$refs) this.$refs.child1.changePlan(val) } }}</script><style></style>child1组件
<template> <div id="child1-wrap" class="child1-wrap"> {{plan}} </div></template><script>import EventBus from '@/components/EventBus'export default { name: 'child1', data () { return { plan: 'I\'m going to have a move tomorrow' } }, methods: { changePlan (val) { this.plan = val } }, created () { // EventBus.$on('changePlanByChild2', (val) => { // this.plan = val // }) }}</script><!-- Add "scoped" attribute to limit CSS to this component only --><style scoped>.child1-wrap { font-size: 30px; color: brown;}</style>child2组件
<template> <div id="child2-wrap" class="child2-wrap"> <input type="text" @input="changePlan"> </div></template><script>export default { name: 'child2', data () { return { } }, methods: { changePlan (e) { this.$emit('changeChild1', e.target.value) } }}</script><style scoped>.child2-wrap { font-size: 28px; color: aqua;}</style>在这里,我们知道了如何在父组件中访问子组件的内容,同时也实现了我们需要的效果