# vue 组件间的通信
# 1、props(父 -> 子)、$emit(子 -> 父)
<!--父组件-->
<template>
<div>
<Child :title='title' @updateTitle='changeTitle'></Child>
</div>
</template>
<script>
import Child from './child.vue';
export default {
data() {
return {
title: '标题'
};
},
components: {
Child
},
methods: {
changeTitle(value) {
this.title = value;
}
}
};
</script>
<!--子组件-->
<template>
<div @click='communicate'>{{title}}</div>
</template>
<script>
export default {
props: ['title'],
methods: {
communicate() {
this.$emit('updateTitle', '新标题');
}
}
}
</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
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
总结:该方法常用于直接父子关系进行通信,对于祖先关系的组件采用这种方式较为繁琐
# 2、sync、update双向绑定
<!--父组件-->
<template>
<div>
<Child :title.sync='title'></Child>
</div>
</template>
<script>
import Child from './child.vue';
export default {
data() {
return {
title: '标题'
};
},
components: {
Child
}
};
</script>
<!--子组件-->
<template>
<div @click='communicate'>{{title}}</div>
</template>
<script>
export default {
props: ['title'],
methods: {
communicate() {
this.$emit('update:title', '新标题');
}
}
}
</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
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
总结:该方法采用双向绑定的方式,相比第一种方式更简洁。
# 3、中央事件总线
<!--父组件-->
<template>
<div>
<Child1></Child1>
<Child2></Child2>
</div>
</template>
<script>
import Child1 from './child1.vue';
import Child2 from './child2.vue';
window.bus = new Vue();
export default {
components: {
Child1,
Child2
}
};
</script>
<!--子组件1-->
<template>
<div @click='communicate'>child1</div>
</template>
<script>
export default {
methods: {
communicate() {
bus.$emit('updateTitle', '新标题');
}
}
}
</script>
<!--子组件2-->
<template>
<div>{{title}}</div>
</template>
<script>
export default {
data() {
return {
title: ''
}
},
mounted() {
bus.$on('updateTitle', (val) => {
this.title = val
});
}
}
</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
52
53
54
55
56
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
52
53
54
55
56
# 4、$children获取子组件的值、$parent获取父组件的值
<!--父组件-->
<template>
<div>
<Child></Child>
</div>
</template>
<script>
import Child from './child.vue';
window.bus = new Vue();
export default {
components: {
Child
},
mounted() {
console.log(this.$children[0].$data)
}
};
</script>
<!--子组件-->
<template>
<div @click='communicate'>{{name}}</div>
</template>
<script>
export default {
data() {
return {
name: '123'
}
},
methods: {
communicate() {
console.log('loged');
}
}
}
</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
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
# 5、v-model
v-model会传一个value的属性和input的事件给子级,子级里可以通过$emit来触发父组件值的更新,在开发组件时,这种方法可很好的实现数据的双向绑定,组件的调用方的值保持和组件内部一致。
<!--父组件-->
<template>
<div>
<Child v-model="title"></Child>
</div>
</template>
<script>
import Child from './child.vue'
export default {
data() {
return {
title: '标题'
};
},
components: {
Child
}
};
</script>
<!--子组件-->
<template>
<div @click="updateTitle">
{{value}}
</div>
</template>
<script>
export default {
props: ['value'],
methods: {
updateTitle() {
this.$emit('input', 'newTitle');
}
}
}
</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
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
# 6、provide、inject
在父组件中通过provide来提供变量,在子组件中通过inject来引入。这里不仅限于子组件,子孙组件也可以,但provide、inject传递的值不是相应式的
<!--父组件-->
<template>
<div>
<Child></Child>
</div>
</template>
<script>
import Child from './child.vue'
export default {
provide: {
for: '标题'
},
components: {
Child
}
};
</script>
<!--子组件-->
<template>
<div>
{{title}}
</div>
</template>
<script>
export default {
inject: ['for'],
data() {
return {
title: this.for
}
}
}
</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
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
# 7、Vuex实现
← SVG 微信分享朋友、朋友圈 →