Vue 中的各类组件通信总结

Author Avatar
Crown 9月 20, 2017
  • 在其它设备中阅读本文章

Vue2的组件通信主要包括父子通信以及兄弟组件的通信这两种大的情况, 希望我的这篇文章能在自己总结知识点的同时, 也能在一定程度上帮到对这里一直有一些模糊的同学, 提前撒花!!!

父子组件的通信

这里假设我们需要在我们的父组件parent.vue中像子组件childPeter.vue中通信:

父组件传递数据给子组件

按照 Vue 的官网介绍, 父往子组件中传递数据是通过 Prop 来传递数据的, 我们的父子组件一般会向像下面这个样子来写:

// parent.vue
<template>
    <childPeter :prop-data="mockData.data1">//这里是要绑定动态的 props才加上的 : ,如果不需要,直接去掉即可
    </childPeter>
</template>

<script>
import childPeter from './childPeter.vue'
export default {
    data() {
        return {
            mockData: { //模拟的数据
                data1: 'hello',
                data2: ['hello', 'world']
            }
        }
    },
    components: {
        childPeter
    }
}
</script>
// childPeter.vue
<template>
    <div>{{ propData }}</div>
</template>

<script>
export default {
    props: ['propData']
}
</script>

这里有一点需要注意的是, 传到子组件里的 prop 数据我们是不能进行操作的, 这里是 vue 默认单向绑定的设置造成的, 但有时间我们不得不对数据进行一些改动时, 我们应该在我们的子组件中将拿到的数据做一个转存, 类似于下面这样:

// childPeter.vue
<template>
    <div>{{ dataSet.slice(0,3) }}</div>
</template>

<script>
export default {
    props: ['propData']
    data() {
        return {
            dataSet: this.propData
        }
    }
}
</script>

在上面的例子上再晋升一步就是Vue中数据的双向绑定了, 即我在子组件中修改了数据, 父组件中的数据也会随之变化, 这里也顺便一起说了(vue 2.3版本最新更新,又可以使用.async语法糖来实现双向绑定了, 下面的也可以来作为一个参考):

<template>
    <div>{{ dataSet.slice(0,3) }}</div>
</template>

<script>
export default {
    props: ['propData']
    computed: {
        dataSet () {
            return this.propData.trim()
        }
    },
}
</script>

父组件调用子组件属性或方法

这个相对就比较简单了, 我们直接给子组件起一个名字. 将名字设置为子组件 rel 属性的值

<childAllen ref="allen"></childAllen>

父组件中通过 $refs.组件名 来获得子组件,也就可以调用子组件的属性和方法了.

var child = this.$refs.aName
child.属性
child.方法()

这里还有一点需要提下, 我们可以在父组件通过 $children 来获得所有直接子组件(父组件的子组件的子组件不算是直接子组件)。但这里需要注意的是 $children 并不保证顺序,也不是响应式的。

Vue 在 V2.1.0 版本后增加了的 Scoped Slots 的特性。该特性支持在子组件的 slot 中用子组件的数据。详情见这里

子组件传递数据给父组件

子组件通过事件传递父组件传数据。子组件通过$emit(eventName)触发事件,父组件通过$on(eventName)监听事件。这里我们继续在最开始的例子上做扩展示例, 大致写法如下所示:

// parent.vue
<template>
    <childPeter :prop-data="mockData.data1" @returnData="showNewData">
    </childPeter>
</template>

<script>
import childPeter from './childPeter.vue'
export default {
    data() {
        return {
            mockData: { //模拟的数据
                data1: 'hello',
                data2: ['hello', 'world']
            }
        }
    },
    components: {
        childPeter
    },
    methods: {
        showNewData(val){
            this.mockData.data2 = val.data
        }
    }
}
</script>
// childPeter.vue
<template>
    <div>{{ propData }}</div>
</template>

<script>
export default {
    props: ['propData'],
    methods: {
        returnData() {
            this.$emit('returnData',{
                name: 'Peter',
                data: xxxx
            })
        }
    }
}
</script>

子组件调用父组件属性或方法

子组件可以通过 $parent 获得父组件,通过 $root 获得最上层的组件。这个跟上面父组件调用子组件的方法相似, 就不在多花代码来描述了.

兄弟组件间的通信

这里一般有两种方法, 一种是官网推荐的推荐的用事件订阅的方式来做, 另外就是vuex了, 这里对于后种我们就不多讨论了, 一般来说vuex都是用来做大型项目的状态管理的, 简单一点的逻辑用第一种方法就行了.

首先我们先创建一个 Vue 对象

// bus.js
export default new Vue();

使用$on全局监听

import Bus from '../bus.js';
export default {
  ready() {
    Bus.$on('loadSuccess', text => {
      this.show = true;
      this.status = 'loadSuccess'
      if (text) {
        this.text = text;
      }
    })
  },
}

使用$emit触发事件

ajax({
  url: Config.API_ADDRESS_ADD,
  type: 'post',
  dataType: 'json',
  data: data
}).then((data)=>{
    Bus.$emit('loadSuccess', '添加成功!');
}).catch((data)=> {
})

这里我们还可以这样做: 使用$once注册一次,触发之后即被销毁;使用$off解绑事件


随着我自己个人的技术水平的提高,我也会尽最大力量去原创一些有价值有内容的文章出来。在此期间我的文章会同步更新在以下地方,欢迎大家在自己长逛的网站中关注或者star我的Github来了解我的最新消息!!!推荐大家收藏关注我的博客网站crowncj.com,因为我的最新更改与文章只会在这里更新,其他地方的文章可能会存在更新不及时或者忘记更新等问题。

未经允许,不准转载