vue2.0中的组件通信

vue中组件是模块化开发的基础,在组件A中使用了组件B,那他们必然需要数据通信,父组件要将数据传递给自组建,子组件要通知父组件自己内部发生的事情。

在vue.js中父子组件的关系可以总结为props down, events up,父组件通过props向下传递数据给子组件,子组件通过events给父组件反馈消息,引用官方的一张图,来看看他们是怎么工作的

1、父子组件通信

①父组件向子组件传递数据,子组件需要显式的用props选项声明它期待接受的数据

父组件传递数据:

<parent> 
    <child :msg="msg"></child>
</parent>

export default {
    data() {
         return {
              msg: [1, 2, 3] 
         }
    }
}

子组件接收数据:
export default {
    props: {
        msg: {
            type: Array,
            default() {
                return [] // 这里可以写默认值
            }
        }
     }
}

初学者常犯的错误是使用字面量语法传递数值

<child some-props="1"></child>

它是一个字面prop,传递的是字符串1,而不是number,如果想传递number类型的数值,需要使用v-bind。把它的值当作JaveScript表达式计算:

<child v-bind:some-props="1"></child>

在vue中,子组件是不允许直接修改父组件通过props传递过来的数据,这样会导致父组件和子组件耦合,并且父组件的数据可能会被任意子组件修改,另外每次父组件更新,子组件相应的props都会更新为最新值。之所以想修改props中的数据是因为:

1、我们希望把props中的数据当作局部数据使用

2、希望把props中的数据处理成其他数据使用

对于这两种方式我们应该正确的处理为:

定义一个局部变量,并用props的值初始化它
props: {
    someProp: {
        type: String,
        default: ""
    }
},
data () {
    return {
        initData: this.someProp
    }
}

定义一个computed,处理props的值并返回
props: {
    someProp: {
        type: String,
        default: ""
    }
},
computed: {
    normalData() {
        return this.someProp.trim().toLowerCase()
    }
}

需要注意的是:JavaScript中数组和对象是引用类型,指向同一内存空间,如果props是数组或对象,在子组件内部直接改变它会影响父组件的状态。

②子组件与父组件通信

我们知道,父组件是使用 props 传递数据给子组件,但如果子组件要把数据传递回去,应该怎样做?那就是自定义事件!
父组件可以直接在子组件使用的地方使用v-on绑定事件

父组件绑定事件和传递数据:
<parent> 
    <child @upup="change" :msg="msg"></child> //监听子组件触发的upup事件,然后调用change方法 
</parent>

export default {
    data() {
        return {
            msg: '123'
        }
    },
    methods: { 
        change(msg) { 
            this.msg = msg; // 接收子组件传递过来的参数,并更新msg,从而子组件也相应的更新msg
        } 
    }
}

子组件接收数据和触发事件:
<template> 
    <div @click="up">{{msg}}</div>
</template> 

export default {
    props: {
        msg: {
            type: String,
            default: ''
        }
    },
    methods: { 
        up() { 
            this.$emit('upup','updateMsg'); //主动触发upup方法,'updateMsg'为向父组件传递的数据 
        } 
    }
}

③ 父组件如何触发子组件的事件

<parent @click="doSomeThing">
    <child ref="childComp"></child>
</parent>

export default {
    methods: {
        doSomeThing() {
            this.$refs.childComp.yesSir('123')
        }
    }
}

<template></template>

export default{
    methods: {
        yesSir(a) {
            console.log(a) // 123
        }
    }
}

2、非父子组件通信

在简单的场景下,vue建议我们使用一个空的 Vue 实例作为中央事件总线:

新建一个bus.js用于存储我们空的事件中转站:

import Vue from 'vue'

export var bus = new Vue()

组件a通过$on绑定事件:

<template>
</template>
import { bus } from 'bus.js'
export default {
    created() {
        bus.$on('change', () => { //接收事件
            this.msg = 'hehe';
        });
    }
}

组件b通过$emit绑定事件:

<div @click="eve"></div>

import { bus } from 'bus.js'
export default {
    methods: {
        eve() {
            bus.$emit('change','hehe'); //触发事件
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值