Vue组件传值的几种常用方式(三)

208 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

Vue组件传值的几种常用方式(三)

大家好,在上一篇文章中我们介绍了子组件向父组件传值的逻辑思想和代码实现,今天我们来学习兄弟组件之间的传值过程。

第三种:兄弟组件之间的传值

兄弟组件之间的传值可以理解为要把兄弟B里的值传递给兄弟A,核心思想是使用eventBus解决方案,在数据发送方内部使用"xxx.$emit(...)"的方法,把想发送的数据通过eventBus方案传递给数据接收方,数据接收方通过如下的方式来接收数据

数据接收方接收数据方式 : xxx.$on(...)

实现效果

QQ录屏20220914115239[00_00_01--00_00_21].gif

点击按钮后,弟弟给哥哥发送信息并打印在哥哥相对应的区域中

文件配置

这里关于vue文件配置很简单,一共需要我们操作的文件有四个,分别是

  • oldBrother.vue

  • youngBrother.vue

  • main.js

  • eventBus.js

如图

image.png

本文将oldBrother.vue统称为哥哥文件,将youngBrother.vue统称为弟弟文件

两个兄弟文件内部快速生成vue结构,将弟弟文件导入到哥哥文件并注册使用,此时前者是数据发送方,后者是数据接收方。这里关于eventBus.js文件我们稍后讲解的时候进行生成,在main.js文件中引入哥哥文件,将其放入进render函数中

image.png

这样一来我们就完成了文件的基本配置

弟弟文件内部完善

与前面一样,现在我们来完善弟弟文件内部的代码

<template>
  <div class="box2">
    <h2>{{ msg }}</h2>
    <button @click="sendMsg">点击向哥哥发送数据</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      msg: '我是弟弟',
    }
  },

  methods() {
    // ...
  },
}
</script>

<style lang="less"></style>

此时我们定义好了数据源msg,点击button按钮触发sendMsg数据,并把这个值传到哥哥文件中,我们需要借助eventBus方案。所以我们现在手动创建一个eventBus.js文件,如图

image.png

注意这个js文件内部的格式要与图中的一致,现在我们需要在哥哥和弟弟文件中都分别导入这个js文件

image.png

现在我们继续完善弟弟文件传值的过程,我们需要借助 “bus.$emit” 固定格式的方法(这个bus是我们引入js文件时单独定义的昵称),如图

image.png

括号内部的字符串 “share” 稍后需要传到哥哥文件中,后面的this.msg就是弟弟文件中的数据源msg的值,这样一来弟弟文件内部代码就相对清晰了

哥哥文件内部完善

<template>
  <div class="box">
    <h1>嗨,我是哥哥~ 弟弟发来的数据是 ---{{ str }}</h1>
    <youngBrother></youngBrother>
  </div>
</template>

<script>
// 导入文件
import youngBrother from '@/components/youngBrother.vue'
import bus from '@/components/eventBus.js'

export default {
  components: {
    youngBrother,
  },
  data() {
    return {
      str: '',
    }
  },

  created() {
    bus.$on('share', (val) => {
      console.log(val)
      this.str = val
    })
  },
}
</script>

<style lang="less">
.box {
  h1 {
    color: red;
  }
}
</style>

我们来分析哥哥文件中的重点代码构成,首先在哥哥文件内部定义数据源str,值为空字符串,并在template模板中利用插值表达式来进行渲染。

此时哥哥需要接收弟弟的数据,于是我们利用利用bus.$on方法,后面括号内部第一个字符串必须与弟弟文件中的传递过来的“share”保持一致,后面函数的形参val就是弟弟传递过来的具体的数据源 'msg'

然后我们要把val的值赋值给str,完成对str原来的值的覆盖 , 整个bus.$on方法需要至少需要定义在生命周期函数created()中,因此至少在这个阶段我们才能使用导出模块内部的数据、props自定义属性、方法等。

思考:能把这里的created()替换成mounted()吗?

此时打开终端运行npm run serve 命令,把项目跑起来之后就实现了我们预期的效果

image.png

image.png

本章总结

兄弟组件之间传值,首先自定义生成eventBus.js文件,并导入到兄弟文件内部。发送方利用bus.$emit( )方法传值,接收方利用bus.on( )方法接收,并至少在created( )周期中使用。关于vue的生命周期和生命周期函数我们后面会进行讲解

本节代码

哥哥文件

<template>
  <div class="box">
    <h1>嗨,我是哥哥~ 弟弟发来的数据是 ---{{ str }}</h1>

    <youngBrother></youngBrother>
  </div>
</template>

<script>
// 导入文件
import youngBrother from '@/components/youngBrother.vue'
import bus from '@/components/eventBus.js'

export default {
  components: {
    youngBrother,
  },
  data() {
    return {
      str: '',
    }
  },

  mounted() {
    bus.$on('share', (val) => {
      console.log(val)
      this.str = val
    })
  },
}
</script>

<style lang="less">
.box {
  h1 {
    color: red;
  }
}
</style>

弟弟文件

<template>
  <div class="box2">
    <h2>{{ msg }}</h2>
    <button @click="sendMsg">点击向哥哥发送数据</button>
  </div>
</template>

<script>
import bus from '@/components/eventBus.js'
export default {
  data() {
    return {
      msg: '哥哥你好呀!我是弟弟',
    }
  },

  methods: {
    sendMsg() {
      console.log(1)
      bus.$emit('share', this.msg)
    },
  },
}
</script>

<style lang="less"></style>