首页 > 其他 > 详细

vue 兄弟组件是如何通信的

时间:2020-10-21 14:33:45      阅读:26      评论:0      收藏:0      [点我收藏+]

今天面试被问到这个问题,我自己思考的是让父组件做两个子组件之间的桥梁,但是我并没有去说,感觉是有些low啊,面试完了赶紧查查是怎么通信的;

就是我自己设想的这种方法也是解决问题的一种方法;

兄弟组件通讯

在Vue中实现兄弟组件的通讯也有几种方法,其中一种方法是让父组件允当两个子组件之间的中间件(中继);

另一种就是使用EventBus(事件总线),它允许两个子组件之间直接通讯,而不需要涉及父组件。

这里就要好好了解下EventBus(事件总线)的概念了;

1、通过父组件进行兄弟组件之间通讯

先来看第一个方法,就是让兄弟组件通过一个共同的父组件彼此通讯。

我们还是通过示例来学习。接下来的这个示例包含父组件和两个子组件,这两个子组件是兄弟组件。单击兄弟组件上的按钮,可以看到他们之间可以相互通讯。

 

 技术分享图片

 首先创建ParentCard组件:

<!-- ParentCard.vue -->

<template>

  <div class="card">

    <div class="card-header">

      <h5 v-text="theCardTitle"></h5>

      <button @click="momSaidChill" v-if="stopFighting()" class="btn">停止通讯</button>

    </div>

    <div class="card-body">

      <brother-card :messageSon="messageson" @brotherSaid="messageDaughter($event)"></brother-card>

      <sister-card :messageDaughter="messagedaughter" @sisterSaid="messageSon($event)"></sister-card>

    </div>

  </div>

</template>

<script>

import BrotherCard from ‘./BrotherCard‘;

import SisterCard from ‘./SisterCard‘

export default {

  name: ‘ParentCard‘,

  data: () => ({

    theCardTitle: ‘父组件‘,

    messagedaughter:‘‘,

    messageson:‘‘

  }),

  components: {

    BrotherCard,

    SisterCard

  },

  methods: {

    messageDaughter(message) {

      this.messagedaughter = message;

    },

    messageSon(message) {

      this.messageson = message;

    },

    stopFighting() {

      if (this.messagedaughter && this.messageson) {

        return true

      }

      return false

    },

    momSaidChill() {

      this.messagedaughter = ‘‘,

      this.messageson = ‘‘

    }

  }

}; 

</script>

创建SisterCard组件:

<!-- SisterCard.vue -->

<template>

  <div class="message">

    <div class="message-header">

      <h5 v-text="theCardTitle"></h5>

    </div>

    <div class="message-body">

      <p class="message-text">我是Sister组件</p>

      <button @click="messageBrother" class="btn">给哥哥发消息</button>

      <div v-if="messageDaughter" class="alert" v-html="messageDaughter"></div>

    </div>

  </div>

</template>

<script>

export default {

  name: ‘SisterCard‘,

  props: [‘messageDaughter‘],

  data: () => ({

    theCardTitle: ‘子组件2‘

  }),

  methods: {

    messageBrother() {

      this.$emit(‘sisterSaid‘, ‘妈妈说,该做作业了!(^_^)!!!‘)

    }

  }

}

</script>

接着创建BrotherCard组件:

<!-- BrotherCard.vue -->

<template>

  <div class="message">

    <div class="message-header">

      <h5 v-text="theCardTitle"></h5>

    </div>

    <div class="message-body">

      <p class="message-text">我是Brother组件</p>

      <button @click="messageSister" class="btn">给妹妹发消息</button>

      <div v-if="messageSon" class="alert" v-html="messageSon"></div>

    </div>

  </div>

</template>

<script>

export default {

  name: ‘BrotherCard‘,

  props: [‘messageSon‘],

  data: () => ({

    theCardTitle: ‘子组件1‘

  }),

  methods: {

    messageSister() {

      this.$emit(‘brotherSaid‘, ‘妈妈说,该做作业了!(^_^)!!!‘)

    }

  }

}

</script>

最终效果如下:

接下来简单看看这个实现过程。

SisterCard通过ParentCardBrotherCard通讯

首先来看SisterCard是如何与BrotherCard通讯的。从示例中可以看出,他们两之间的通讯是通过其父组件ParentCard作为中间媒介来进行通讯的。

我们在SisterCard组件的<template>中为messageBrother()方法设置了一个@click事件来监听该事件。

<button @click="messageBrother" class="btn">给哥哥发消息</button>

当用户点击SisterCard中的“给哥哥发消息”将会触发messageBrother()方法。在这个方法中,将发出一个sisterSaid事件,并且把妈妈说,该做作业了!(^_^)!!!信息发送出去。

methods: {

  messageBrother() {

    this.$emit("sisterSaid", "妈妈说,该做作业了!(^_^)!!!");

  

}

ParentCard<template>中定制了一个@sisterSaid事件侦听器,它触发了messageSon()方法。所以父组件在这两个兄弟组件之间起到了传递的作用。

<sister-card :messageDaughter="messagedaughter" @sisterSaid="messageSon($event)"></sister-card>

另外在ParentCard组件中声明了messageSon()方法,该方法接受上面发送的自定义事件,并将其设置为messageson属性。

这样一来,ParentCard组件中messageson就由空字符串变成了妈妈说,该做作业了!(^_^)!!!

接着在ParentCard组件自定义标签<brother-card>通过:messageSon="messageson"的方式将messageson属性绑定到<brother-card>

<brother-card :messageSon="messageson" @brotherSaid="messageDaughter($event)"></brother-card>

这个时候在BrotherCard组件中设置props的属性值为messageSon。这样就可以访问源自于SisterCard组件的数据,并且该数据在BrotherCard中显示。

props: ["messageSon"],

最后在BrotherCard组件就可以使用该数据。我们可以通过v-if指令来查看messageSon是否有任何有用的数据,如果有,那么就在div.alert中显示该消息:

<div v-if="messageSon" class="alert" v-html="messageSon"></div>

上面的描述过程也适用于BrotherCard通过ParentCardSisterCard进行数据通讯。

 

2、通过EventBus进行兄弟间组件通讯

随着应用程序越来越庞大,通过父组件来传递所有内容会把事情变得越来越棘手。不过我们还有另一种选择,那就是使用EventBus架起兄弟之间通讯的桥梁。接下来看看我们是如何利用这一点一完成兄弟组件之间的数据通讯。

我们同样基于上面的示例来做修改。接下来的示例中,ParentCard组件包含了SisterCardBrotherCard两个子组件,而且这两个子组件是兄弟组件。

首先在main.js文件中定义一个新的eventBus对象,其实他是一个全新的Vue实例:

// main.js

import Vue from ‘vue‘

import App from ‘./App‘

export const eventBus = new Vue()

new Vue({

  el: ‘#app‘,

  render: h => h(App)

})

接着在新创建的BrotherCard组件导入main.js

<!-- BrotherCard.vue -->

<script>

import { eventBus } from ‘../main‘

</script>

eventBus实例现在将成为BrotherCard组件中发出事件的实例。现在我们可以使用eventBus.$emit来替代上例中的this.$emiteventBus是一个Vue实例,而且eventBus有这个$emit方法,这就是我们能够这么用的原因。这样做同样会触发相同的自定义事件名称和消息。

methods: {

  messageSister() {

    eventBus.$emit(‘brotherSaid‘, ‘妈妈说,该做作业了!(^_^)!!!‘)

  }

同样可以在SisterCard组件中引入eventBus

<script>

import { eventBus } from ‘../main‘

</script>

created()生命周期钩子添加到SisterCard组件。在created()钩子中添加eventBus启动自定义事件的侦听器。当使用SisterCard组件时,该侦听器将开始运行并且会保持运行。下面的代码只是侦听brotherSaid自定义事件,然后触发回调,将作为自定义事件有效负载传递的消息分配给fromBrother

created() {

  eventBus.$on(‘brotherSaid‘, (message) => {

    this.fromBrother = message

  })

这样就可以有条件地显示来自BrotherCard的信息:

<div v-if="fromBrother" class="alert" v-html="fromBrother"></div>

上面看到的是如何通过eventBus实现SisterCardBrotherCard传递数据的方式,反之,BrotherCard向SisterCard`传递数据也可以使用类似的方式。

最终代码如下:

<!-- SisterCard.vue -->

<template>

  <div class="message">

    <div class="message-header">

      <h5 v-text="theCardTitle"></h5>

    </div>

    <div class="message-body">

      <p class="message-text">我是Sister组件</p>

      <button @click="messageBrother" class="btn">给哥哥发消息</button>

      <div v-if="fromBrother" class="alert" v-html="fromBrother"></div>

    </div>

  </div>

</template>

<script>

import { eventBus } from "../main";

export default {

  name: "SisterCard",

  data: () => ({

    theCardTitle: "Sister Card",

    fromBrother: ""

  }),

  methods: {

    messageBrother() {

      eventBus.$emit("sisterSaid", "妈妈说,该做作业了!(^_^)!!!");

    }

  },

  created() {

    eventBus.$on("brotherSaid", message => {

      this.fromBrother = message;

    });

  }

};

</script>

<!-- BrotherCard.vue -->

<template>

  <div class="message">

    <div class="message-header">

      <h5 v-text="theCardTitle"></h5>

    </div>

    <div class="message-body">

      <p class="message-text">我是Brother组件</p>

      <button @click="messageSister" class="btn">给妹妹发消息</button>

      <div v-if="fromSister" class="alert" v-html="fromSister"></div>

    </div>

  </div>

</template>

<script>

import { eventBus } from "../main.js";

export default {

  name: "BrotherCard",

  data: () => ({

    theCardTitle: "Brother Card",

    fromSister: ""

  }),

  methods: {

    messageSister() {

      eventBus.$emit("brotherSaid", "妈妈说,该做作业了!(^_^)!!!");

    }

  },

  created() {

    eventBus.$on("sisterSaid", message => {

      this.fromSister = message;

    });

  }

};

</script>

最后创建的ParentCard组件,我们可以像下面这样编码:

<!-- ParentCard -->

<template>

  <div class="card">

    <div class="card-header">

      <h5 v-text="theCardTitle"></h5>

    </div>

    <div class="card-body">

      <brother-card></brother-card>

      <sister-card></sister-card>

    </div>

  </div>

</template>

<script>

import BrotherCard from "./BrotherCard";

import SisterCard from "./SisterCard";

export default {

  name: "ParentCard",

  data: () => ({

    theCardTitle: "Parent Card"

  }),

  components: {

    BrotherCard,

    SisterCard

  }

};

</script>

总结

在本教程中,我们学习了在Vue中如何实现组件之间的通讯。通过实例看到了如何实现父组件向子组件,子组件向父组件以及兄弟组件间的数据通讯。简单的根据为:

  • 通过props可以实现父组件向子组件发送数据
  • 通过自定义事件可以实现子组件向父组件发送数据
  • 兄弟组件数据通讯除了借助共同的父组件做为通讯桥梁之外,还可以通过eventBus来让兄弟之间组件进行数据通讯

最后用一张图来简单的描述一下:

技术分享图片

 

原文: https://www.w3cplus.com/vue/component-communication.html 

 ps:希望大家早日成为前端大神,哈哈哈


 

vue 兄弟组件是如何通信的

原文:https://www.cnblogs.com/zhilu/p/13851827.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!