组件之间的数据共享
# 组件之间的数据共享
# 1. 组件之间的关系
在项目开发中,组件之间的关系分为如下 3 种:
① 父子关系
② 兄弟关系
③ 后代关系
# 2. 父子组件之间的数据共享
父子组件之间的数据共享又分为:
① 父、子共享数据
② 子、父共享数据
③ 父、子双向数据同步
# 2.1 父组件向子组件共享数据
父组件通过 v-bind 属性绑定向子组件共享数据。同时,子组件需要使用 props 接收数据。示例代码如下:
// 父组件
<template>
<h2>app根组件</h2>
<button @click="count += 1">+1</button>
<hr>
<son :name="name" :count="count"></son>
</template>
<script>
import son from './son.vue'
export default {
name:'MyApp',
data(){
return{
name:'星月',
count:0
}
},
components:{
son
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 子组件
<template>
<h2>son子组件</h2>
name:{{ name }}
count:{{ count }}
</template>
<script>
export default {
name:'MySon',
props:['name','count']
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
点击父组件的button,count成功传递到子组件:
# 2.2 子组件向父组件共享数据
子组件通过自定义事件的方式向父组件共享数据。示例代码如下:
<!-- 父组件 -->
<template>
<h2>app根组件---{{ this.count }}</h2>
<button @click="count += 1">+1</button>
<hr>
<son @addcount="getadd"></son>
</template>
<script>
import son from './son.vue'
export default {
name:'MyApp',
data(){
return{
name:'星月',
count:0
}
},
components:{
son
},
methods: {
getadd(con){
this.count = con
}
},
}
</script>
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
<!-- 子组件 -->
<template>
<h2>son子组件</h2>
<button @click="add">+1</button>
count:{{ count }}
</template>
<script>
export default {
name:'MySon',
emits:['addcount'],
data(){
return{
count:0
}
},
methods: {
add(){
this.count += 1
this.$emit('addcount',this.count)
},
},
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 2.3 父子组件之间数据的双向同步
父组件在使用子组件期间,可以使用 v-model 指令维护组件内外数据的双向同步:
① 在 v-bind: 指令之前添加 v-model 指令
② 在子组件中声明 emits 自定义事件,格式为 update:xxx
③ 调用 $emit() 触发自定义事件,更新父组件中的数据
app.vue代码
<template>
<h1>app根组件{{ count }}</h1>
<button @click="add">+1</button>
<hr>
<mymode v-model:mycount="count"></mymode>
</template>
<script>
import mymode from './mode.vue'
export default {
name:'MyApp',
data(){
return{
count:1
}
},
components:{
mymode
},
methods:{
add() {
this.count++
}
}
}
</script>
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
mode.vue代码
<template>
<h2>model子组件</h2>
count的值:{{ mycount }}
<button @click="add">+1</button>
</template>
<script>
export default {
name:'mymodel',
props:['mycount'],
emits:['update:mycount'],
methods:{
add() {
this.$emit('update:mycount',this.mycount + 1)
}
}
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 3. 兄弟组件之间的数据共享
兄弟组件之间实现数据共享的方案是 EventBus。可以借助于第三方的包 mitt 来创建 eventBus 对象,从而实
现兄弟组件之间的数据共享。示意图如下:
# 3.1 安装 mitt 依赖包
在项目中运行如下的命令,安装 mitt 依赖包:
npm install mitt@2.1.0
# 3.2 创建公共的 EventBus 模块
在项目中创建公共的 eventBus 模块如下:
// 导入mitt包
import mitt from 'mitt'
// 创建 eventBus实例对象
const bs = mitt()
// 将实例导出
export default bs
2
3
4
5
6
7
8
# 3.3 在数据接收方自定义事件
在数据接收方,调用 bus.on('事件名称', 事件处理函数) 方法注册一个自定义事件。示例代码如下:
<template>
<hr>
<h2>rigth数据接收--{{ count }}</h2>
</template>
<script>
import bs from './eventBus.js'
export default {
data(){
return{
count:0
}
},
created() {
bs.on('add',(e)=>{
this.count = e
})
},
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 3.4 在数据接发送方触发事件
在数据发送方,调用 bus.emit('事件名称', 要发送的数据) 方法触发自定义事件。示例代码如下:
<template>
<h2>left数据发送方</h2>
{{ count }}
<button @click="add">+1</button>
</template>
<script>
import bs from './eventBus.js'
export default {
data(){
return{
count:0
}
},
methods: {
add(){
this.count += 1
bs.emit('add',this.count)
}
},
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
在数据发送方点击++,接收放数据跟着同步:
# 4. 后代关系组件之间的数据共享
后代关系组件之间共享数据,指的是父节点的组件向其子孙组件共享数据。此时组件之间的嵌套关系比较复杂,可以使用 provide 和 inject 实现后代关系组件之间的数据共享。
# 4.1 父节点通过 provide 共享数据
父节点的组件可以通过 provide 方法,对其子孙组件共享数据:
<template>
<h2>app根组件</h2>
<hr>
<lift></lift>
</template>
<script>
import lift from './left.vue'
import rigth from './rigth.vue'
export default {
name:'MyApp',
data(){
return{
name:'星月',
count:0 // 定义需要共享的数据
}
},
provide(){ // 把需要共享的数据 return 出去
return{
count:this.count
}
},
components:{
lift,
rigth,
},
}
</script>
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
# 4.2 子孙节点通过 inject 接收数据
子孙节点可以使用 inject 数组,接收父级节点向下共享的数据。示例代码如下:
<template>
<hr>
<h2>三级组件</h2>
共享过来的count: {{ count }}
</template>
<script>
export default {
inject:['count'] // 使用 inject 接收共享过来的数据
}
</script>
2
3
4
5
6
7
8
9
10
11
12
# 4.3 父节点对外共享响应式的数据
父节点使用 provide 向下共享数据时,可以结合 computed 函数向下共享响应式的数据。示例代码如下:
<script>
import { computed } from 'vue' //从vue中按需导入 computed 函数
export default {
name:'MyApp',
data(){
return{
// 定义需要共享的数据
count:1
}
},
provide() { // 把需要共享的数据 return 出去
return { // 使用computed 函数,把数据包装为响应式的数据
count:computed(() => this.count)
}
},
components:{
lift,
rigth,
},
}
</script>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 4.4 子孙节点使用响应式的数据
如果父级节点共享的是响应式的数据,则子孙节点必须以 .value 的形式进行使用。示例代码如下:
<template>
<hr>
<h2>三级组件</h2>
共享过来的count: {{ count.value }}
</template>
<script>
export default {
inject:['count']
}
</script>
2
3
4
5
6
7
8
9
10
11
# 5. vuex
vuex 是终极的组件之间的数据共享方案。在企业级的 vue 项目开发中,vuex 可以让组件之间的数据共享变得高 效、清晰、且易于维护。
# 6. 总结
- 父子关系
① 父 、子 属性绑定;
② 子、父 事件绑定;
③ 父、子互传组件上的 v-model;
- 兄弟关系
④ EventBus
- 后代关系
⑤ provide & inject
- 全局数据共享
⑥ vuex(后面单独学习)