Vue 2.0学习笔记:不同场景下组件间的数据通讯

发布于 大漠

通过前面的学习,对于Vue中组件的数据交流有了一定的了解。实际上在Vue中不同场景之下组件之间的数据通讯是不一样的,在业务中常见的组件通讯的场景主要有父子组件之间的通讯、兄弟组件间的通讯和全局组件的通讯等三种。只不过全局组件的通讯不是我们这章要阐述的范围,他涉及到Vuex。接下来分别看看父子组件和兄弟组件之间的通讯方式和实现方法。

父子组件间的数据通讯

父子组件间的数据通讯可以分为:父组件传递数据给子组件子组件传递数据给父组件两种。

在《组件数据传递》一文中我们知道了,在Vue中,父组件传递数据给子组件时,可以通过props来完成。

上图简单的描述了,在Vue中父组件的数据通过props传递给子组件。具体示例如下:

子组件传递数据给父组件有两种方式:回调参数自定义事件。先来看回调函数的方式,如图:

简单的看一个小示例:

<div id="app">
    <h3>{{ parentComponentName }}</h3>
    <child :change-parent-component-name = "changeParentComponentName"></child>
</div>

<template id="child">
    <div>
        <button @click = "() => changeParentComponentName(newComponentName)">点击我</button>
    </div>
</template>


let parent = new Vue({
    el: '#app',
    data () {
        return {
            parentComponentName: 'w3cplus'
        }
    },
    methods: {
        changeParentComponentName: function (newComponentName) {
            this.parentComponentName = newComponentName
        }
    },
    components: {
        'child': {
            template: '#child',
            data () {
                return {
                    newComponentName: '大漠'
                }
            },
            props: {
                changeParentComponentName: {
                    type: Function,
                    default: () => {  }
                }
            }
        }
    }
})

上面的示例父组件通过props给子组件传递了一个changeParentComponentName函数,然后在子组件调用这个函数的时候,以参数的形式传递一个子组件内部的newComponentName数据给这个函数。这样在父组件中定义的函数changeParentComponentName就可以取得子组件传来的newComponentName参数

当你点击蓝色按钮(子组件)时,父组件的名称就会由“w3cplus”换成“大漠”:

除了回调函数的方式之外,还有类似于在《实现组件数据的双向绑定》一文中介绍的方式,即自定义事件

把上面回调函数的示例修改成自定义事件的方法:

<div id="app">
    <h3>{{ parentComponentName }}</h3>
    <child v-on:change-parent-component-name = "changeParentComponentName"></child>
</div>

<template id="child">
    <div>
        <button @click="clickCallback">点击我</button>
    </div>
</template>

let parent = new Vue({
    el: '#app',
    data () {
        return {
            parentComponentName: 'W3cplus'
        }
    },
    methods: {
        changeParentComponentName: function (componentName) {
            this.parentComponentName = componentName
        }
    },
    components: {
        'child': {
            template: '#child',
            data () {
                return {
                    parentComponentName: '大漠'
                }
            },
            methods: {
                clickCallback: function () {
                    this.$emit('change-parent-component-name', this.parentComponentName)
                }
            }
        }
    }
})

上面的代码在子组件中通过$emit(event,[...options])自定义了一个change-parent-component-name事件,所有的参数据将被传递给监听器回调,也就是在父组件中通过methods定义的changeParentComponentName方法,从而实现从子组件中给父组件传参。

最终得到的效果和回调函数的方式是一样的。

兄弟组件间的数据通讯

上面我们展示的是父子组件间的数据通讯。但在具体的业务,总是难免会碰到兄弟组件间的数据通讯。比如firstChildsecondChild两个组件都是parent组件的子组件,而且firstChildsecondChild两个组件间存在数据通讯。打个比方来说,点击secondChild组件的按钮来改变firstChild组件的名称。这样的一个效果如何实现,看代码吧。

<template id="child1">
    <div>
        <h3>{{ firstChildComponentName }}</h3>
    </div>
</template>

<template id="child2">
    <div>
        <button @click="changeFirstChildComponentName">点击我</button>
    </div>
</template>

<div id="app">
    <h2>{{ parentComponentName }}</h2>
    <first-child :first-child-component-name="firstChildComponentName"></first-child>
    <second-child :change-first-child-component-name="changeFirstChildComponentName"></second-child>
</div>

let app = new Vue({
    el: '#app',
    data () {
        return {
        parentComponentName: 'W3cplus',
        firstChildComponentName: '大漠'
        }
    },
    methods: {
        changeFirstChildComponentName: function () {
            this.firstChildComponentName = 'Airen'
        }
    },
    components: {
        'firstChild': {
            template: '#child1',
            props: {
                firstChildComponentName: {
                    type: String,
                    default: ''
                }
            }
        },
        'secondChild': {
            template: '#child2',
            props: {
                changeFirstChildComponentName: {
                    type: Function,
                    default: () => {}
                }
            }
        }
    }
})

效果如下:

这个时候点击secondChild的按钮时,firstChild组件的名称会从“大漠”变成“Airen”。

secondChild通过调用函数来修改firstChild的数据。其原理是:寻找其共同的父组件,使用数据和相关方法“提升”到父组件内部,并向下传给两个子组件。其中一个子组件取得数据,另一个子组件取得了改变数据的方法

总结

通过《组件数据传递》、《实现组件数据的双向绑定》和今天这篇文章的学习。简单的了解了Vue中的组件数据通讯方式:

  • 通过props从父组件向子组件传递数据,实现父组件传递数据给子组件
  • 通过回调函数自定义事件从子组件向父组件传递数据,实现子组件传递数据给父组件

再次验证:父子组件的关系总结为:prop向下传递,事件向上传递。

对于兄弟组件间的数据通讯,它们将会寻找其共同的父组件,使用数据和相关方法“提升”到父组件内部,并向下传给两个子组件。其中一个子组件取得数据,另一个子组件取得了改变数据的方法

大漠

常用昵称“大漠”,W3CPlus创始人,目前就职于手淘。对HTML5、CSS3和Sass等前端脚本语言有非常深入的认识和丰富的实践经验,尤其专注对CSS3的研究,是国内最早研究和使用CSS3技术的一批人。CSS3、Sass和Drupal中国布道者。2014年出版《图解CSS3:核心技术与案例实战》。

如需转载,烦请注明出处:https://www.fedev.cn/vue/component-data-and-props-part3.htmljordan retro 11 mens mens