Vue2+Ts之Provide / Inject用法

在Vue.js项目中,当需要在父组件和多个深层子组件之间传递数据时,使用Prop可能会变得复杂。此时,可以利用Vue的Provide/Inject特性简化这一过程。在提供的例子中,父组件通过@Provide传递一个包含name、age和isCheckd的对象,子组件则通过@Inject接收并显示这些数据。通过点击按钮,父组件可以改变isCheckd的值,实时更新在子组件中的展示。这种方式提高了代码的可维护性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Provide / Inject的定义

Provide / Inject: 父级组件向其所有子孙后代注入一个依赖(@Provide ),不论组件层次有多深,都可以通过(@Inject)接收父级组件传过来的任何类型的值,并在其上下游关系成立的时间里始终生效。

最近在写项目的时候,常需要对多个子组件的表单进行编辑/查看模式的切换,一开始用Prop进行传值进行控制,当组件多的时候使用Prop还是挺繁琐的,这样的话,使用 Provide / Inject就可以快速实现功能的切换

父组件

<template>
  <div>
  <!-- 引用子组件 ProvideInject -->
    <ProvideInject />
    <a-button type="primary" @click="isCheckdBtn()">isCheckd</a-button>
  </div>
</template>

<script lang="ts">
import { Component, Emit, Prop, Provide, Vue, Watch } from 'vue-property-decorator';
import ProvideInject from './components/ProvideInject.vue';

@Component({
  components: { ProvideInject },
})
export default class ProvideIndex extends Vue {
  @Provide('provideObject')//定义@Provide将provideObject对象传给子组件
  provideObject: { name: string; age: number; isCheckd: boolean } = { name: 'Provide', age: 100, isCheckd: false };

  isCheckdBtn() {
    this.provideObject.isCheckd = true;
  }
}
</script>

子组件

<template>
  <div>
    <h1>我是子组件--{{ provideObject }}</h1>
  </div>
</template>

<script lang="ts">
import { Component, Emit, Inject, Prop, Vue, Watch } from 'vue-property-decorator';

@Component
export default class ProvideInject extends Vue {
  @Inject() provideObject: { name: string; age: number; isCheckd: boolean };// 定义@Inject()对父组件传过来的值进行接收
}
</script>

在这里插入图片描述

### Vue3 `provide` 和 `inject` 功能及用法 #### 实现组件间通信的方法概述 在 Vue 3 中,`provide` 和 `inject` 是一种用于跨层级传递数据的有效机制。这使得祖先组件能够向其任意后代组件提供数据或函数,而不必通过中间的每一层手动传递属性。 当使用 `props` 进行父子组件间的通信时,对于深层次嵌套结构中的子孙组件来说,这种方式可能会显得繁琐且不易维护。相比之下,`provide`/`inject` 可以简化这一过程,允许更灵活的数据流动[^3]。 #### 使用示例 下面展示了一个简单的例子来说明如何利用 `provide` 和 `inject` 来实现不同层次级组件之间的通讯: ```javascript // App.vue (父组件) <template> <div id="app"> <child-component /> </div> </template> <script setup> import { provide, ref } from 'vue'; import ChildComponent from './ChildComponent.vue'; const message = ref('Hello from parent!'); provide('message', message); // 向下提供名为 "message" 的变量 </script> ``` ```html <!-- GrandChildComponent.vue --> <template> <p>{{ injectedMessage }}</p> <!-- 显示来自顶层的消息 --> </template> <script setup> import { inject } from 'vue'; const injectedMessage = inject('message'); // 获取由上级提供的 "message" </script> ``` 在这个案例里,即使 `GrandChildComponent` 并不是直接位于 `App.vue` 下面的一级子组件,仍然可以通过 `inject` 接收到 `App.vue` 所提供的 `message` 数据[^2]。 #### 类型安全与只读保护 为了确保类型安全性,在 TypeScript 环境下应当为注入的对象指定相应的类型定义;另外还可以借助于 `readonly` 关键字防止意外修改被共享的状态值[^5]。 例如: ```typescript // Parent.ts import { readonly, Ref } from 'vue' export interface MyInterface { text: string; } const myData: Ref<MyInterface> = reactive({text:'hello'}) provide('myKey', readonly(myData)) ``` ```typescript // Child.ts import { inject } from 'vue' import type { MyInterface } from './Parent' const data = inject<MyInterface>('myKey') if (!data) throw new Error("Injection failed!") console.log(data.text); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值