一、父子组件通信
(1)、父组件传递数据给子组件,使用props属性来实现
父组件:
<child message="love!"></child>
子组件:
Vue.component('child', {
// 声明 props
props: ['message'],
// 就像 data 一样,prop 也可以在模板中使用
// 同样也可以在 vm 实例中通过 this.message 来使用
template: '<span>{{ message }}</span>'
})
结果:
love
(2)动态:父组件数据如何传递给子组件
父组件:
<child :my-message="parentMsg"></child>
data(){
return {
parentMsg: [1,2,3,4,5]
};
}
子组件:通过props属性接收数据
// 方式一
props: ['myMessage']
// 方式二
props: {
myMessage: Array //指定传入的类型,如果类型不对,会警告
}
// 方式三
props: {
myMessage: {
type: Array,
default: [5,6,7] //指定默认的值
}
}
props属性验证有以下形式:
Vue.component('example', {
props: {
// 基础类型检测 (`null` 指允许任何类型)
propA: Number,
// 可能是多种类型
propB: [String, Number],
// 必传且是字符串
propC: {
type: String,
required: true
},
// 数值且有默认值
propD: {
type: Number,
default: 100
},
// 数组/对象的默认值应当由一个工厂函数返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定义验证函数
propF: {
validator: function (value) {
return value > 10
}
}
}
})
2、子组件与父组件通信
vue是单向数据传递的,如果子组件直接改变父组件传过来的数据是不允许的。但是可以通过触发事件通知父组件改变数据,实现改变子组件的目的。
子组件:
<div @click="childClick()"></div>
methods: {
childClick() {
this.$emit('tell','hello'); //主动触发tell方法,'hello'为向父组件传递的数据
}
}
父组件:
<child @tell="change" :msg="msg"></child> //监听子组件触发的tell事件,然后调用change方法;msg是父组件传给组件的数据
methods: {
change(msg) {
this.msg = msg;
}
}
二、非父子组件通信
有时候,非父子关系的两个组件之间也需要通信。在简单的场景下,可以使用一个空的 Vue 实例作为事件总线。原理就是把 Vue 实例当作一个中转站。
var bus = new Vue(); // 创建事件中心
// 触发组件 A 中的事件
<div @click="eve"></div>
methods: {
eve() {
bus.$emit('change','hehe'); //bus触发事件
}
}
// 在组件 B 创建的钩子中监听事件
<div></div>
created() {
bus.$on('change', () => { // bus接收事件
this.msg = 'hehe';
});
}
方法2:
在初始化web app的时候,main.js给data添加一个 名字为eventhub 的空vue对象。就可以使用 this.$root.eventHub 获取对象。
new Vue({
el: '#app',
router,
render: h => h(App),
data: {
eventHub: new Vue()
}
})
在组件内调用事件触发
//通过this.$root.eventHub获取此对象
//调用$emit 方法
this.$root.eventHub.$emit('eventName', data)
在另一个组件调用事件接受,移除事件监听器使用$off方法
this.$root.eventHub.$on('eventName', (data)=>{
// 处理数据
})