不管组件层次结构有多深;父组件有一个 provide 选项来提供数据,子组件有一个 inject 选项来开始使用这个数据。
- api https://v3.cn.vuejs.org/guide/component-provide-inject.html
- 响应式更改数据需要写组合式api写法 忘掉vue2的methods和data 都要在setup中实现
provide和inject组合式写法 依赖注入响应式数据变化
- provide inject实现父子传值的时候。子组件也会影响父组件
- app根组件
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<template>
<div>
改变根组件的------ <span style="color:red">{{title_}}</span>
<button @click="setTitle">改变根组件的数据</button>
<br>
<input type="text" v-model="userName">
<props_></props_>
</div>
</template>
<script>
export default {
name: 'App',
setup(){
//依赖注入 深层嵌套组件传值
let title_ = ref('依赖注入 ----- 我是app根组件的title');
let userName = reactive({
userName:'admin',
age:'20'
});
provide('title',title_);
provide('userName',userName);
let setTitle = ()=>{
title_.value = '依赖注入 ----- 我是更改过后的app根组件的title';
};
return {
title_,
setTitle,
...toRefs(userName)
}
},
components: {
props_
}
}
</script> - props_组件的子组件 多层组件嵌套
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23<template>
<div>
components-组件 ------- {{title}}
<br>
ueseName:{{userName}}
<br>
<input type="text" v-model="userName.userName">
</div>
</template>
<script>
import {inject} from 'vue'
export default {
setup(){
const title = inject('title', '我是默认标题' /* 默认值 */);
const userName = inject('userName');
return{
title,
userName
}
}
}
</script>provide和inject 非组合式api写法(没法响应式更改数据)
- app父组件
- provide要想获取到data中的数据需要写成方法
但是这种写法provide和inject就没法动态响应式的改变数据
1
2app ------------- {{title}}
<button @click="setTitle">修改父组件title</button>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22import {provide } from 'vue';
export default {
//需要注入多层嵌套组件的数据
provide(){
return{
title: this.title,
ueseInfo:{
name:'用户名',
}
}
},
data(){
return{
title: '我是app根组件下边的8组件下的components_组件的标题',
}
},
methods:{
setTitle(){
this.title = '改变app组件的title'
}
},
} - 多层级嵌套组件 app > 子组件 > 孙组件 > 需要依赖注入传参的组件children
children组件 并不会随着父组件数据的更改而响应式变化
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<template>
<div>
com-组件 ------- {{title }}
<br>
ueseName:{{ueseInfo}}
</div>
</template>
<script>
import {inject} from 'vue'
export default {
name: "components",
inject: ['title','ueseInfo'],
created() {
console.log(`Injected property: ${this.title}`)
},
}
</script>