②vue组件之间的通信(不包含vuex)

297 阅读2分钟

第二种:兄弟节点之间的通信

两个兄弟节点之间的通信: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>

在这里,我们知道了如何在父组件中访问子组件的内容,同时也实现了我们需要的效果