父子通信

props和emit

父组件通过props传递数据给子组件,子组件通过emit发送事件传递给父组件。

// 父组件<div>    <child :data="child" @send="getFromChild"></child></div>data(){    return{        toChild: '大儿子',        fromChild: ''    }},methods: {    getFromChild(val){        this.fromChild=val    }}// 子组件<div @click="toParent">{{data}}</div>props:[data],methods: {    toParent(){        this.$emit('send', '给父亲')    }}

v-model

v-model其实是props,emit的语法糖,v-model默认会解析成名为value的prop和名为input的事件。

// 父组件<children v-model="msg"></children><p>{{msg}}</p>data(){    return{        msg:'model'    }}// 子组件<input :value="value" @input="toInput" />props: ['value'],methods: {    toInput(e){        this.$emit('input', e.target.value)    }}

$children和$parent

在父组件使用$children访问子组件,在子组件中使用$parent访问父组件

// 父组件<child />data(){    return {        msg: '父组件数据'    }},methods: {    test(){        console.log('我是父组件的方法,被执行')    }},mounted(){    console.log(this.$children[0].child_msg); // 执行子组件方法}// 子组件<div>{{$parent.msg}}</div>data(){    return{        child_msg: '子组件数据'    }},mounted(){    // 子组件执行父组件方法    this.$parent.test(); }

.sync方式

在vue1.x中是对prop进行双向绑定,在vue2只允许单向数据流,也是一个语法糖

// 父组件<child :count.sync="num" />data(){    return {        num: 0    }}// 子组件<div @click="handleAdd">add</div>data(){    return {        counter: this.count    }},props: ["count"],methods: {    handleAdd(){        this.$emit('update:count', ++this.counter)    }}

跨多层次组件通信

依赖注入

可以使用provide/inject,虽然文档中不推荐直接使用在业务中。
假设有父组件A,然后有一个跨多层次的子组件B

// 父组件Aexport default{    provide: {        data: 1    }}// 子组件Bexport default{    inject: ['data'],    mounted(){        // 无论跨几层都能获取父组件的data属性        console.log(this.data); // 1    }}

$listeners和$attrs

$attrs--包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外)。
inheritAttrs--默认值true,继承所有父组件属性(除props),为true会将attrs中的属性当做html的data属性渲染到dom根节点上
$listeners--包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,v-on="$listeners"将所有事件监听器指向这个组件的某个特定子元素

// 父组件<children :child1="child1" :child2="child2" @test1="onTest1"@test2="onTest2"></children>data(){    return {        child1: 'childOne',        child2: 'childTwo'    }},methods: {    onTest1(){        console.log('test1 running')    },    onTest2(){        console.log('test2 running')    }}// 子组件<p>{{child1}}</p><child v-bind="$attrs" v-on="$listeners"></child>props: ['child1'],mounted(){    this.$emit('test1')}// 孙组件<p>{{child2}</p><p>{{$attrs}}</p>props: ['child2'],mounted(){    this.$emit('test2')}

任意组件

可以用Vuex或Event Bus解决

Event Bus

1.新建一个bus.js文件

import Vue from 'vue';export default new Vue();

2.使用它

<div @click="addCart">添加</div>import Bus from 'bus.js';export default{    methods: {        addCart(event){            Bus.$emit('getTarget', event.target)        }    }}// 另一组件export default{    created(){        Bus.$on('getTarget', target =>{            console.log(target)        })    }}

Vuex方式

参考链接:
https://juejin.im/post/5c776e...
https://segmentfault.com/a/11...