β

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

W3CPlus 50 阅读

通过前面的学习,对于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 方法,从而实现从子组件中给父组件传参。

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

兄弟组件间的数据通讯

上面我们展示的是父子组件间的数据通讯。但在具体的业务,总是难免会碰到兄弟组件间的数据通讯。比如 firstChild secondChild 两个组件都是 parent 组件的子组件,而且 firstChild secondChild 两个组件间存在数据通讯。打个比方来说,点击 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.w3cplus.com/vue/component-data-and-props-part3.html

作者:W3CPlus
原文地址:Vue 2.0学习笔记:不同场景下组件间的数据通讯, 感谢原作者分享。

发表评论