22
为了方便展示,所有的组件都是以单文件组件的方式编写的

1. 父组件对子组件通信

在父组件内,在子组件上使用v-bind动态绑定attribute,在子组件内使用props传递attribute

如下是父组件

<template>
  <div id="app">
    <child :message="title"/>
    <!--使用v-bind绑定message,箱子组件传递message-->
  </div>
</template>

<script>
  import Child from './components/Child' // 导入子组件

  export default {
    name: 'App',
    components: {Child}, // 注册子组件
    data() {
      return {
        title: '父组件向我传递了信息'
      }
    }
  }
</script>

如下是子组件

<template>
  <div id="app">
    {{message}}
  </div>
</template>

<script>
  export default {
    props: ['message'] // 使用props传递数据
  }
</script>

2.子组件对父组件通信

子组件对父组件通信我们只能通过自定义事件去进行触发,而无法像父对子通信那样直接进行数据传递

首先我们必须了解Vue暴露两个实例方法

  • vm.$emit( event, […args] ),触发vm实例上的事件,附加参数都会传给监听器回调
  • vm.$on( event, callback ),监听vm实例上的自定义事件,事件可以由vm.$emit触发,回调函数会接收所有传入事件触发函数的额外参数

总结一下:我们用$on去监听一个自定义事件,这个自定义事件由$emit触发,触发的同时将data放在附加参数里,传给$on接收

如下是父组件

<template>
  <div id="app">
    <child v-on:receiveData="consoleData"/>
    <!--监听自定义事件receiveData,监听到之后触发consoleData获取子组件传递的数据-->
  </div>
</template>

<script>
  import Child from './components/Child' // 导入子组件

  export default {
    name: 'App',
    components: {Child}, // 注册子组件
    methods: {
      consoleData(data) {
        // 这里的data是由$emit传递来的数据
        console.log(data) // ["子组件向我传递信息啦", "测试"]
      }
    }
  }
</script>

如下是子组件

<template>
  <div id="app">
    <button @click="transData">点我,向父组件传递数据</button>
    <!--绑定transData事件,以便执行器内部的$emit-->
  </div>
</template>

<script>
  export default {
    data() {
      return {
        message: '子组件向我传递信息啦',
        title: '测试'
      }
    },
    methods: {
      transData() {
        // 触发自定义事件receiveData,将数据传递给父组件
        this.$emit('receiveData', [this.message, this.title])
      }
    }
  }
</script>

3.兄弟组件之间进行通信

主要我们通过全局注册一个eventBus单文件组件,这个组件的作用充当着vm.$emit( event, […args] )里的vm
也就是说:

  • 自定义事件绑定在eventBus这个实例上
  • eventBus.$on('receiveData', data => {}),eventBus监听自定义事件
  • eventBus.$emit('receiveData', arg1..),eventBus触发自定义事件

新建一个js文件,作为EventBus

import Vue from 'vue' // 导入vue模块

export default new Vue({}) // 新建一个空的vue实例作为EventBus

如下是父组件

<template>
  <div id="app">
    <!--两个子组件-->
    <child1/>
    <child2/>
  </div>
</template>

<script>
  import Child1 from './components/Child' // 导入子组件1
  import Child2 from './components/child2' // 导入子组件2

  export default {
    name: 'App',
    components: {Child1, Child2}// 注册两个子组件
  }
</script>

如下是子组件1

<template>
  <div>
    <button @click="transData">点我,向兄弟组件Child2传递数据</button>
    <!--绑定transData事件,以便执行器内部的$emit-->
  </div>
</template>

<script>
  import eventBus from './EventBus' // 导入EventBus

  export default {
    data() {
      return {
        message: 'Child2,你好呀',
        title: '测试'
      }
    },
    methods: {
      transData() {
        // 通过EventBus触发自定义事件receiveData,将数据传递给Child2组件
        eventBus.$emit('receiveData', [this.message, this.title])
      }
    }
  }
</script>

如下是子组件2

<template>
  <div>
    <h1>我的兄弟组件Child1向我传递了信息:{{message}}</h1>
    <!--绑定transData事件,以便执行器内部的$emit-->
  </div>
</template>

<script>
  import eventBus from './EventBus' // 导入EventBus

  export default {
    data() {
      return {
        message: ''
      }
    },
    created() {
      eventBus.$on('receiveData', data => {
        // 注意这里使用箭头函数是因为需要将this绑定父级的context,否则this指向eventBus
        this.message = data
      })
    }
  }
</script>
如果你不使用单组件文件,可以看下面的例子
<div id="app">
    <child1></child1>
    <child2></child2>
</div>

<script>
// 将新的vue实例绑定到prototype上
Vue.prototype.bus = new Vue() // 新建一个空的vue实例作为EventBus

Vue.component('child1', {
    template: `
      <div>
        <button @click="transData">点我,向兄弟组件Child2传递数据</button>
      </div>
    `,
    data() {
        return {
            message: 'Child2,你好呀',
            title: '测试'
        }
    },
    methods: {
        transData() {
            // 通过EventBus触发自定义事件receiveData,将数据传递给Child2组件
            this.bus.$emit('receiveData', [this.message, this.title])
        }
    }
})

Vue.component('child2', {
    template: `
        <div>
          <h1>我的兄弟组件Child1向我传递了信息:{{message}}</h1>
        </div>
        `,
    data() {
        return {
            message: ''
        }
    },
    created() {
        this.bus.$on('receiveData', data => {
            // 注意这里使用箭头函数是因为需要将this绑定父级的context,否则this指向eventBus
            this.message = data[0]
        })
    }
})

let vm = new Vue({
    el: '#app'
})
</script>

bluesboneW
784 声望79 粉丝

今天,你帮助了社区