兄弟组件传值

在这里插入图片描述

  • 兄弟组件之间彼此没有联系,它们需要通过中间Vue实例对象bus(快递员)进行数据传递。

1. 声明事件

给组件实例(或Vue实例) 声明事件有两种方式:

  1. 直接声明
  2. 通过$on实现

给组件实例声明事件:

<组件 @事件名称="事件驱动方法"></组件>

通过$on进行声明:

// 语法:
组件实例.$on(事件名称,事件驱动方法(形参,形参){})
// 例如:
// 声明事件
vm.$on('hello',function(traffic,city){console.log(`我坐着{$traffic}到达${city}城市`)})

注意:组件实例 和 vue实例 都可以调用$on。

2. 兄弟组件传值

实现步骤

  1. 定义模块 src/bus.js,内容就是导入Vue模块,并导出一个Vue实例对象:

    import Vue from 'vue'
    export default new Vue() 
    
  2. 在各个兄弟组件中,导入 bus.js 模块:

    import bus from '@/bus.js'
    

    虽然bus.js被各个组件都导入,但是系统中bus只有一份。

  3. 接收数据的兄弟组件的 created 生命周期方法里(使得事件及时响应),发送数据的组件中声明

    使用 bus.$on(‘事件名称’, (接收的数据) => {}) 定义事件成员方法

    created(){
      // 定义事件,注意箭头函数应用
      bus.$on('xxx', data=>{
        console.log(data)
      })
    }
    

    xxx是事件方法的名称。data是形参,待接收数据,并且可以定义多个。

    注意:如果$on内部要使用this,请通过"箭头函数"声明方法。

  4. 发送数据的兄弟组件中,使用 bus.$emit(‘事件名称’, 要发送的数据) 来向外发送参数。

    <button @click="sendMsg">传值</button>
    export default {
      methods: {
        sendMsg(){
          // 触发绑定的事件,并向外传递参数。
          bus.$emit('xxx', '1000元保护费')
        }
      }
    }
    

第一个参数xxx 是接收数据组件给bus声明的方法。第二个参数是传递的实参数据。

说明

  1. Vue实例可以调用$on()方法进行事件方法创建

    实例.$on(名称,(形参,形参,形参……){})
    

    参数根据需要,可以是一个或多个。

  2. Vue实例可以调用$emit()方法进行事件方法执行

    实例.$emit(名称,实参,实参,实参……)
    

    参数 与 $on的形参是一一对应的。

注意

虽然各个兄弟组件针对bus.js都有做引入,系统在运行的时候只有一个bus对象,故大哥 给 bus绑定的事件方法,兄弟组件可以通过bus调用。

案例应用

兄弟组件传值

src/bus.js代码:

// 快递员,负责兄弟组件之间传递数据
import Vue from 'vue'
// 导出一个Vue对象
// 注意:这是一个新的对象,与main.js里边的没有关系
export default new Vue()

First.vue代码(created、$on设置事件方法,准备接受数据):

<template>
    <div id="first">
      <h3>大哥组件</h3>
      <span>{{dt}}</span>
    </div>
</template>

<script>
// 导入bus的模块对象
import bus from '@/bus.js'

export default {
  name: 'First',
  data () {
    return {
      dt: ''
    }
  },
  // 第一时间就把事件声明好,以便小弟调用并传递数据
  created () {
    // 实例对象.$on(事件名称,function(形参,形参){}事件事件的回调方法)
    // 注意:回调函数变为箭头函数,使得this可以正确使用
    bus.$on('jieshou', msg => {
      // console.log(msg)
      // 把数据给dt接收
      this.dt = msg
    })
  }
}
</script>

Second.vue代码(bus调用$emit()调动事件进行数据传递):

<template>
    <div id="second">
      <h3>小弟组件</h3>
      <button @click="back()">给大哥回话</button>
    </div>
</template>

<script>
// 导入bus的模块对象
import bus from '@/bus.js'

export default {
  name: 'Second',
  methods: {
    // 给大哥组件传值
    back () {
      // 使得bus调用自己的事件(是大哥给bus声明的)
      // bus.$emit(事件,参数,参数)
      bus.$emit('jieshou', '1000元保护费')
    }
  }
}
</script>

App.vue代码(引入、注册、使用各个兄弟组件):

<template>
  <div id="app">
    <h2>App根组件</h2>
    <first></first>
    <second></second>
  </div>
</template>

<script>
// 引入、注册、使用 两个兄弟组件
import First from './components/First.vue'
import Second from './components/Second.vue'

export default {
  components: {
    First,
    Second
  }
}
</script>
Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐