当前位置:   article > 正文

【Vue2/3】使用Provide/Inject 依赖注入跨组件通信

【Vue2/3】使用Provide/Inject 依赖注入跨组件通信

历史小剧场

什么东西,都有使用年限,比如大米、王朝。
不同的是,大米的年限看得见,王朝的年限看不见。看不见,却依然存在。对于气数,崇祯是不信的,开始不信。等到崇祯十四年,怕什么来什么,后院起火,前院也起火,卢象昇死了,辽东白了,中原乱了,信了。

前言

  • 在组件嵌套多层情况下,不论组件嵌套多深,父组件都可以通过provide来提供数据,子组件或孙组件或曾孙组件使用inject注入数据。
  • 还有,在兄弟组件之间传值也很方便。

Vue2-OptionsAPI使用

什么是optionsAPI?

我的理解就是,像一个对象里面的属性方法都算是optionsAPI,所以,在Vue2中都是以这样的格式来编写代码的。

案例

App.vue

export default {
  provide: {
    // 丧失响应式
    name: '李四'
  },
  ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Father.vue

<template>
    <div>
        <TestProvideOptionsAPIChild />
    </div>
</template>

<script lang="ts">
import TestProvideOptionsAPIChild from './TestProvideOptionsAPIChild.vue';

export default {
    name: "TestProvideOptionsAPIFather",
    components: {
        TestProvideOptionsAPIChild
    },
}
</script>

<style lang="scss" scoped>

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

TestProvideOptionsAPIChild.vue

<!--  -->
<template>
    <div>
        <h1>{{ name }}</h1>
    </div>
</template>

<script lang="ts">
export default {
    name: "TestProvideOptionsAPIChild",
    inject: ["name"],
}
</script>

<style lang="scss" scoped>

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Vue3-CompositionAPI使用

在组合式API中,我们需要在setup()函数期间调用,或者在setup 语法糖里使用,必须从vue显示导入provide/inject方法

案例

App.vue

export default {
  setup() {
    const name = ref<string>("张三")

    const changeName = () => {
      name.value = '王五'
    }

    // 使用readonly包裹,使其不可在子组件被修改
    provide('name', readonly(name))
    provide('age', 20)
    provide('sex', '男')
    provide('hobby', '跑步')
    provide("changeName", changeName)
  }
  ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Father.vue

<!--  -->
<template>
    <div>
        <TestProvideChild />
    </div>
</template>

<script setup lang="ts">
import TestProvideChild from './TestProvideChild.vue'
</script>

<style lang="scss" scoped>

</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

TestProvideChild.vue

<!-- TestProvideChild.vue -->
<template>
    <div>
        <h1>{{ name }}</h1>
        <h1>{{ age }}</h1>
        <h1>{{ sex }}</h1>
        <h1>{{ hobby }}</h1>
        <button @click="changeName">修改姓名</button><br>
        <button @click="injectChangeName">子组件修改姓名</button><br>
    </div>
</template>

<script setup lang="ts">
import { inject } from 'vue';

// inject() 方法第二个参数为默认值
let name = inject('name', ''),
      age = inject('age', 0),
      sex = inject('sex', 'unknown'),
      hobby = inject('hobby', ""),
      changeName = inject('changeName', () => {});

const injectChangeName = () => {
    name.value = '心潮'
}
</script>

<style lang="scss" scoped>

</style>
  • 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

【默认规则】当我们使用provide/inject来实现组件通信的时候,必须在父组件中去修改数据,在子组件不可以自行去修改数据,所以,我们可以在父组件中使用provide传递数据时可以将数据使用readonly()方法去包裹。如此,在子组件中去修改就修改不了了,否则的话,是可以修改的。这样,对以后项目的数据维护不友好

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/菜鸟追梦旅行/article/detail/694079
推荐阅读
相关标签
  

闽ICP备14008679号