一、父子组件通信
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)=>{
// 处理数据
})
二、非父子组件通信demo1
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<Achild></Achild>
<Bchild></Bchild>
</div>
<script>
var bus=new Vue();
var Achild = {
template: '<h1 @click="ss">click me 传递给兄弟组件</h1>',
methods:{
ss(){
bus.$emit('change','hello world');
}
}
}
var Bchild = {
data(){
return {
message:''
}
},
template: '<h1>接受上个兄弟传递过来的值: {{message}}</h1>',
created(){
var _self=this;
bus.$on("change",function(id){
_self.message=id;
});
}
}
// 创建根实例
new Vue({
el: '#app',
components: {
// <runoob> 将只在父模板可用
Achild: Achild,
Bchild: Bchild
},
})
</script>
</body>
</html>