官网API: https://cn.vuejs.org/v2/guide/components.html#Prop
一、父子组件通信
1、父组件传递数据给子组件,使用props属性来实现
- 传递普通字符串
父组件:
<child message="hello!"></child>
子组件:
Vue.component('child', { // 声明 props props: ['message'], // 就像 data 一样,prop 也可以在模板中使用 // 同样也可以在 vm 实例中通过 this.message 来使用 template: '<span>{{ message }}</span>' })
结果:
hello!
- 动态:父组件数据如何传递给子组件
父组件:
<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)=>{ // 处理数据 })