# Vue.js 之组件通信的方式
# 父传子
# Prop
# 数组形式接收 prop
<parent>
<child title= "我是标题" content="我是内容"></child>
</parent>
1
2
3
2
3
那么在子组件中就可以使用 props 来接收这个 content :
Vue.component('child',{
// 以数组的形式接收父组件传递的多个数据
props: ['title','content']
});
1
2
3
4
2
3
4
# 对象形式接收 prop
使用对象的形式定义每一个 prop 相关的属性。
Vue.component('child',{
props: {
title: {
// 类型
type: String,
// 默认值
default: '',
// 必需
required: false,
// 自定义校验
validator: function(value) {
}
},
content: {}
}
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# $attrs
<parent>
<child title="我是标题" content="我是内容"></child>
</parent>
1
2
3
2
3
有时候子组件并没有定义自身的 Prop ,那么就可以使用 $attrs 来获取父组件传递的所有属性值。
Vue.component('child',{
mounted: function() {
console.log(this.$attrs.title); // 我是标题
console.log(this.$attrs.content); // 我是内容
}
});
1
2
3
4
5
6
2
3
4
5
6
# $listeners
<parent>
<child @click="click()"></child>
</parent>
1
2
3
2
3
当父组件传递的是一个原生事件的时候,我们可以加上 .native 修饰符,, 这样子组件就可以正确接收。
<parent>
<child @click.native="click()"></child>
</parent>
1
2
3
2
3
也可以使用 $listeners 获取父组件传递的所有事件
Vue.component('child',{
mounted: function() {
console.log(this.$listeners.click()); // 调用 click 事件
}
});
1
2
3
4
5
2
3
4
5
或者在子组件上监听父组件传递的所有事件
Vue.component('child',{
template: '<button v-on=$listeners></button>'
});
1
2
3
2
3
# $children
父组件可以通过 $children 获取到自己下面的所有子组件实例
<parent>
<child></child>
<child></child>
<child></child>
</parent>
<script>
Vue.component('parent',{
mounted: function() {
console.log(this.$children);
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# provide/inject
父组件中使用 provide 提供数据
Vue.componet('parent',{
provide:{
title: '我是标题',
content: '我是内容'
}
});
1
2
3
4
5
6
2
3
4
5
6
子组件中使用 inject 注入数据
Vue.componet('child',{
inject: ['child']
});
1
2
3
2
3
# ref
在父组件中可以使用 ref 特性直接访问一个子组件实例
<parent>
<child ref="child"></child>
</parent>
<script>
Vue.component('parent',{
mounted: function() {
console.log(this.$refs.child);
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 子传父
# Prop
有时候父组件传递给子组件的 prop 是一个对象,那么在子组件中修改了该对象的属性后,父组件同样会受到影响。
<parent>
<child :data="obj"></child>
</parent>
<script>
Vue.component('parent',{
data: {
obj: {
content: '我是内容'
}
}
});
Vue.component('child',{
props: ['data'],
mounted: function() {
// 修改后,父组件中的 content 会变化
this.data.content = '被子组件修改'
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# $emit
我们可以在子组件中触发自定义的事件,在父组件的作用域监听。
<parent>
<child @update="change"></child>
</parent>
<script>
Vue.component('parent',{
methods: {
change: function(value) {
console.log(value); // 打印:子组件传递的数据
}
}
});
Vue.component('child',{
mounted: function() {
this.$emit('update', '子组件传递的数据');
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# .sync
<parent>
<child v-bind:title.sync="title"></child>
</parent>
<script>
Vue.component('parent',{
data: {
title: '我是一个标题'
}
});
Vue.component('child',{
mounted: function() {
this.$emit('update:title', '子组件修改数据');
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
v-bind:title.sync = "title"
等价于 v-bind:title="title" v-on:update:title="title = $event"
# $parent
子组件通过 $parent 获取父组件实例
<parent>
<child></child>
</parent>
<script>
Vue.component('child',{
mounted: function() {
console.log(this.$parent);
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 同级组件
# EventBus
使用一个全局的 Vue 实例作为事件的传递媒介。
<A></A>
<B></B>
<C></C>
<script>
var EventBus = new Vue();
Vue.component('A',{
mounted: function() {
EventBus.$emit('change', 'A 传递的数据');
}
});
Vue.component('B',{
mounted: function() {
EventBus.$on('change',function(data) {
console.log(data);
});
}
});
Vue.component('C',{
mounted: function() {
EventBus.$on('change',function(data) {
console.log(data);
});
}
});
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27