# Vue组件的通信方式
# 父子组件通信
父传子通过props,子传父通过emit。A是父组件,B是子组件。
# 父传子
// A.vue
<template>
<div>
A 组件
<B froma="父组件的数据"/>
</div>
</template>
<script>
import B from './B.vue'
export default {
components: {
B
}
}
</script>
// B.vue
<template>
<div>
B组件-{{froma}}
</div>
</template>
<script>
export default {
props: ['froma']
}
</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
28
29
30
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
28
29
30
# 子传父
// A.vue
<template>
<div>
A 组件 - {{fromb}}
<B @fromb="handleData"/>
</div>
</template>
<script>
import B from './B.vue'
export default {
data () {
return {
fromb: ''
}
},
components: {
B
},
methods: {
handleData (data) {
console.log(data)
this.fromb = data
}
}
}
</script>
// B.vue
<template>
<div>
B组件
<button @click="sendData">发送数据</button>
</div>
</template>
<script>
export default {
methods: {
sendData () {
this.$emit('fromb', 'i am from b')
}
}
}
</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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# 多层级组件通信
# $attrs/$listeners
假设我们有A,B,C三个组件,分别是爷子孙。如果我要把数据从A传给C,平时我们再不用vuex的前提下,一般就是通过A->B,然后B->C,中间B只是个中间传递的角色,B还要一个个接收,明显很冗余麻烦,$attrs和$listeners就是解决这个的。$attrs负责属性传递,$listeners负责事件传递。
// A.vue
<template>
<div>
A 组件
<B :msg="msg" @handleClick="handleClick"/>
</div>
</template>
<script>
import B from './B.vue'
export default {
data () {
return {
msg: '数据'
}
},
components: {
B
},
methods: {
handleClick () {
alert('clicked')
}
}
}
</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
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
// B.vue
<template>
<div>
B组件
<C v-bind="$attrs" v-on="$listeners" />
</div>
</template>
<script>
import C from './C.vue'
export default {
components: {
C
}
}
</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
// C.vue
<template>
<div>
C组件 {{msg}}
<button @click="handleClick">点击</button>
</div>
</template>
<script>
export default {
props: ['msg'],
methods: {
handleClick () {
this.$emit('handleClick')
}
}
}
</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
如上,A组件传递了msg变量,监听了handleClick事件,B组件负责承载A传过来的属性和事件,C就能直接获取属性msg和触发handleClick事件。
# provide/inject
这个官方建议是最好用在高阶插件/组件库提供用例,并不推荐直接用于应用程序代码中。
举个例子,有三个组件A,B,C分别代表爷,子,孙,爷提供的数据,它的后代都能收到。
// A.vue
<template>
<div>
A 组件
<B />
</div>
</template>
<script>
import B from './B.vue'
export default {
provide: {
data: '祖先的数据'
},
components: {
B
}
}
</script>
// B.vue
<template>
<div>
B组件 {{data}}
<C />
</div>
</template>
<script>
import C from './C.vue'
export default {
inject: ['data'],
components: {
C
}
}
</script>
// C.vue
<template>
<div>
C组件 {{data}}
</div>
</template>
<script>
export default {
inject: ['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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# EventBus
在项目不复杂的情况下,这是一种不错的跨组件通信,而无需引入vuex,前提是项目不复杂,开发者少的情况,否则就会很容易出现输数据散落的到处都是。 用法如下:同一层级下新建A.vue,B.vue,C.vue,bus.js
// bus.js
import Vue from 'vue'
export default new Vue()
1
2
3
2
3
// A.vue
<template>
<div>
A 组件
<B />
<C />
<button @click="sendData">发送数据</button>
</div>
</template>
<script>
import Bus from './bus.js'
import B from './B.vue'
import C from './C.vue'
export default {
components: {
B,
C
},
methods: {
sendData () {
Bus.$emit('send', 'hello world')
}
}
}
</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
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
// B.vue
<template>
<div>
B组件 {{data}}
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
data: 'B:'
}
},
mounted() {
Bus.$on('send', data => {
this.data += data
})
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// C.vue
<template>
<div>
C组件 {{data}}
</div>
</template>
<script>
import Bus from './bus.js'
export default {
data () {
return {
data: 'C:'
}
},
mounted() {
Bus.$on('send', data => {
this.data += data
})
},
}
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# vuex
这个是终极方案,在项目很大的时候这个是最佳选择,这个就不多赘述了,最佳资料见官网 (opens new window)
# 补充
还有类似this.$parent获取父组件,this.$children获取子组件,获取后可以调用组件的属性方法等。