vue之组件传值 爷到孙 provide && inject
- 示例:就是当前根组件,可以向子组件传递数据,也可以向孙组件传递数据,这就是provide提供依赖数据的方式,其中接受数据为 inject的方式去接受
使用 provide提供依赖,单个数据,数组形式接受
根组件Main.vue
- 根组件,为子组件或者孙子组件提供数据依赖,进行数据的展示,或者数据的修改
- 01:提供非响应式数据,也就是非 ref,reactive定义的数据
- 传递到子组件的时候,是无法对此数据进行响应式处理的,也就是修改它的值,不会影响视图
- eg: flag 触发事件时候,视图不会发生变化
- 02:提供响应式数据,也就是ref ,reactive定义的数据,
- 传递到子组件时候,是可以修改数据的值,同时影响的是注入的依赖值,同时发生变化的!
- eg: num 触发事件时候,视图会发生变化,提供的依赖值也发生变化,子,孙组件的值同时发生变化
<template>
<div class="main">
我是Main根组件
<B></B>
</div>
</template>
<script setup lang="ts">
import { provide, ref } from 'vue'
import B from './childCom/B.vue'
provide('flag', true)
provide('num', ref<Number>(0))
</script>
<script lang="ts">
export default {
name: 'Main',
}
</script>
<style lang="scss" scoped>
.main {
width: 400px;
height: 400px;
background: #ccc;
}
</style>
子组件 B.vue
<template>
<div class="b">
我是子组件B BFlag -- {{ BFlag }} BNum- {{ BNum }}
<BSon></BSon>
</div>
</template>
<script setup lang="ts">
import { inject } from 'vue'
import BSon from './BSon.vue'
const BFlag = inject('flag')
const BNum = inject('num')
</script>
<script lang="ts">
export default {
name: 'B',
}
</script>
<style lang="scss" scoped>
.b {
background: yellow;
width: 200px;
height: 200px;
}
</style>
BSon.vue
<template>
<div class="bSon">
我是B组件的子组件 bSonFlag - {{ bSonFlag }}
<button @click="changeFlag">我修改了Flag值</button>
bSonNum - {{ bSonNum }}
<button @click="changeNum">我修改了num值</button>
</div>
</template>
<script setup lang="ts">
import { inject, Ref, ref } from 'vue'
let bSonFlag = inject('flag')
let bSonNum = inject<Ref<any>>('num', ref(0))
const changeNum = () => {
bSonNum.value++
}
const changeFlag = () => {
bSonFlag = false
}
</script>
<script lang="ts">
export default {
name: 'BSon',
}
</script>
<style lang="scss" scoped>
.bSon {
background: pink;
width: 150px;
height: 150px;
}
</style>
- 效果
使用 provide提供依赖,多个数据,对象形式
根组件 Main.vue
- 提供一个对象数据,并且再子孙组件之中修改组件的值,同时响应效果
<template>
<div class="main">
我是Main根组件
<B></B>
</div>
</template>
<script setup lang="ts">
import { provide, reactive, ref } from 'vue'
import B from './childCom/B.vue'
type Person = {
name: String
age: Number
}
provide(
'Person',
reactive<Person>({
name: 'pink',
age: 0,
})
)
</script>
<script lang="ts">
export default {
name: 'Main',
}
</script>
<style lang="scss" scoped>
.main {
width: 500px;
height: 500px;
background: #ccc;
}
</style>
B.vue
<template>
<div class="b">
我是子组件B bPerson - {{ bPerson }} <br />
<button @click="changName">我是修改 name</button>
<BSon></BSon>
</div>
</template>
<script setup lang="ts">
import { inject, reactive } from 'vue'
import BSon from './BSon.vue'
const bPerson = inject('Person', reactive({ name: 'pink', age: 0 }))
const changName = () => {
bPerson.name = '我是B组件修改的'
}
</script>
<script lang="ts">
export default {
name: 'B',
}
</script>
<style lang="scss" scoped>
.b {
background: yellow;
width: 430px;
height: 430px;
}
</style>
BSon.vue
<template>
<div class="bSon">
我是B组件的子组件 bSonPerson -- {{ bSonPerson }} <br />
<button @click="changePerson">我修改了Person值</button>
</div>
</template>
<script setup lang="ts">
import { inject, reactive, Ref, ref } from 'vue'
let bSonPerson = inject('Person', reactive({ name: 'pink', age: 0 }))
const changePerson = () => {
bSonPerson.name = '我是BSon组件修改的'
bSonPerson.age = 20
}
</script>
<script lang="ts">
export default {
name: 'BSon',
}
</script>
<style lang="scss" scoped>
.bSon {
background: pink;
width: 300px;
height: 300px;
}
</style>
- 效果