vue的provide与inject如何使用?能否实现双向绑定?

本文详细介绍了Vue中provide与inject的用法,通过一个三层组件嵌套的示例展示了如何使用它们进行数据传递。同时,还探讨了如何利用这两个API实现双向绑定,使得父组件和子组件可以相互影响,更新彼此的状态。这一特性在处理深度嵌套组件间的通信时特别有用。


vue 组件间的通信方式有很多种,所以使用时需要考虑哪种方式是最合适的。若仅仅是简单的隔代组件通信,我认为使用 provide与inject会更加方便。

1. provide与inject用法

作用:实现组件间的通信
适用范围:有一些深度嵌套的组件,而深层的子组件只需要父组件的部分内容。
使用方式:

provide 选项应该是:一个对象或返回一个对象的函数
inject 选项应该是:一个字符串数组,或 一个对象,对象的 [key] 是本地的绑定名

2.使用示例

示例为 Father.vue > Son.vue > GrandSon.vue 三层嵌套结构

Father.vue
父组件进行变量提供,供后代组件使用

<template>
  <div>
    <div>
      <h1>这里是父组件</h1>
      <button @click="changeName">click me</button>
      <Son />
    </div>
  </div>
</template>
<script>
import Son from "./Son";
export default {
  name: "Father",
  components: {
    Son
  },
  // 提供变量,供后代组件使用
  provide() {
    return {
      // 普通提供变量,不会发生响应式变化
      name: this.name,
      // 响应式提供
      getReactiveName: () => this.name
    };
  },
  data() {
    return {
      name: "默认姓名:张三"
    };
  },
  methods: {
    changeName(val) {
      // 修改需要注入的变量
      this.name = "父组件修改后的姓名: 杰森斯坦森·郭达";
    }
  }
};
</script>

Son.vue
此处并无实际意义,仅为了增加组件嵌套层级

<template>
  <div>
    <h4>这里是儿子组件</h4>
    <GS />
  </div>
</template>
<script>
import GS from "@/views/GrandSon.vue";
export default {
  name: "Son",
  components: {
    GS
  }
};
</script>

GrandSon.vue
此为孙组件,进行注入父组件提供的数据

<template>
  <div>
    <h6>
      这里是孙子组件
      <br />
      <br />
      <!-- 普通的使用提供的值 -->
      正常使用:{{name}}
      <br />
      <br />
      <!-- 响应式使用方式1: 直接执行提供的函数-->
      直接执行提供的响应函数: {{getReactiveName()}}
      <br />
      <br />
      <!-- 响应式使用方式2: 使用computed计算属性-->
      使用computed计算属性: {{reactiveNameFromParent}}
    </h6>
  </div>
</template>
<script>
export default {
  name: "GrandSon",
  inject: ["name", "getReactiveName"],
  computed: {
    reactiveNameFromParent() {
      return this.getReactiveName();
    }
  }
};
</script>

点击父组件里的按钮,可以发现父组件内的变量发生了变化,而后代组件内也可以响应式发生变化。

3.provide与inject实现双向绑定

Father.vue
父组件注入的地方多提供一个修改的方法

// ...
  provide() {
    return {
      // 普通注入变量,不会发生响应式变化
      name: this.name,
      // 响应式注入
      getReactiveName: () => this.name,
      // 给后代提供修改变量的方法
      setName: ({ name }) => {
        this.name = name;
      }
    };
  },
// ...

Grandson.vue
孙组件

// ...  多接受一个提供的方法
  inject: ["name", "getReactiveName",'setName'],
// ...
methods: {
    changeName() {
    // 调用父组件提供的方法进行修改
      this.setName({name:'孙组件修改后的姓名: 尼古拉斯·赵四'});
    }
  }

思路:
父组件多提供一个修改父组件内变量的方法,后代组件使用该方法并传递相应参数,父组件变量修改完成后会,后代组件相应的地方会响应式的进行修改。

如此即可实现双向绑定。

### Vue.js 中 `provide` 和 `inject` 的用法 在 Vue.js 中,`provide` 和 `inject` 是一种用于跨组件传递数据的方式。这种方式特别适合于父子组件之间多层嵌套的情况下,避免逐级通过 props 或事件来传递数据。 #### 基本概念 - **Provide**: 父组件可以提供变量给后代组件。 - **Inject**: 后代组件可以从祖先组件注入被提供的变量。 这种机制类似于依赖注入,在大型应用中非常有用,因为它减少了显式的 prop 和 event 链接的需求[^1]。 #### 使用示例 下面是一个简单的例子展示如何使用 `provide` 和 `inject`: ```javascript // 父组件 (ParentComponent.vue) export default { data() { return { message: 'Hello from parent!' }; }, provide() { return { sharedMessage: this.message }; } }; // 子孙组件 (ChildComponent.vue) export default { inject: ['sharedMessage'], mounted() { console.log(this.sharedMessage); // 输出: Hello from parent! } }; ``` 在这个例子中,父组件通过 `provide` 提供了一个名为 `sharedMessage` 的属性,而子孙组件则通过 `inject` 注入了这个属性并可以在其生命周期钩子函数中访问它。 #### 动态更新 Provide 数据 如果希望 `provide` 出的数据能够动态响应变化,则需要借助 Vue 的响应式特性。可以通过返回一个对象或者绑定到 `this` 来实现这一点。 ```javascript // 父组件 (DynamicParentComponent.vue) import { reactive } from 'vue'; export default { setup() { const state = reactive({ count: 0 }); function increment() { state.count++; } return { state, increment }; }, provide() { return { counterState: this.state, incrementCounter: this.increment }; } }; // 子孙组件 (DynamicChildComponent.vue) export default { inject: ['counterState', 'incrementCounter'], mounted() { console.log(this.counterState.count); // 初始值为 0 this.incrementCounter(); console.log(this.counterState.count); // 更新后的值为 1 } }; ``` 在此案例中,不仅提供了状态还提供了修改该状态的方法,使得子孙组件可以直接调用方法改变共享的状态。 #### 注意事项 当使用 `provide` 和 `inject` 时需要注意以下几点: - 被提供的属性不会自动成为响应式的,除非像上面那样手动处理。 - 它们适用于跨越多个层次结构的情况;对于简单的一对一关系,推荐继续使用 Props 和 Events[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值