vue之组件传值 爷到孙 provide && inject

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')
// inject<Ref<any>>('num', ref(0)) 后面的 ref(0)设置默认值,也就是兜底处理
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'
// inject('Person', reactive({ name: '', age: 0 })) 后面的 reactive({ name: '', age: 0 }) 设置默认值,也就是兜底处理
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>
  • 效果
    在这里插入图片描述
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值