Vue高阶用法:provide / inject

今天写项目的时候,需要把父组件的值传给子和孙子,传统的props只能父传子,看了一下vuejs的官方文档,有个provide / inject。

这对选项需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在其上下游关系成立的时间里始终生效。如果你熟悉 React,这与 React 的上下文特性很相似。

提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的 property 还是可响应的。

例子代码如下:

父组件

<!--
 * @Descripttion: 父组件
 * @Author: wu fen fen
 * @Date: 2022-02-08 16:56:29
 * @LastEditors: wu fen fen
 * @LastEditTime: 2022-02-09 15:07:46
-->
<template>
    <div>
        <button @click="add">点击增加</button>
        <provideChild/>
    </div>
</template>
<script>
import provideChild from './provideChild'
export default {
    components: { provideChild },
    //依赖注入传值
    provide() {
        return {
            newFoo: this.obj
        }
    },
    data() {
        return {
          obj: {
            foo: 5
          }
        }
    },
    methods: {
        add() {
            this.obj.foo++
        },
    }
}
</script>

子组件

<!--
 * @Descripttion: 子组件
 * @Author: wu fen fen
 * @Date: 2022-02-09 14:00:48
 * @LastEditors: wu fen fen
 * @LastEditTime: 2022-02-09 14:12:39
-->
<template>
<section>
    <div>我是子组件:{{newFoo.foo}}</div>
    <childChild />
</section>
</template>
<script>
import childChild from './childChild.vue'
export default {
    components: {
        childChild
    },
    inject: ['newFoo'],
    mounted() {
        console.log(this.newFoo)
    },
}
</script>

孙子组件

<!--
 * @Descripttion: 孙子组件
 * @Author: wu fen fen
 * @Date: 2022-02-09 14:01:01
 * @LastEditors: wu fen fen
 * @LastEditTime: 2022-02-09 14:15:31
-->
<template>
    <div>我是孙子组件:{{ newFoo.foo }}</div>
</template>
<script>
export default {
    inject: ['newFoo'],
}
</script>

注意:要传递对象,否则无法改变值

实际项目中运用的代码如下

父组件

<template>
  <div class="gateway">
    <div class="app-container gateway-container">
      <div class="left-part">
        <gateway-table-card
          class="part1"
          ref="gatewwayTableCard"
          @handleOpenEditGatewayDrawer="handleOpenEditGatewayDrawer"
          @gatewayTableRowClick="handleGatewayTableRowClick"
        />
        <monitoring-center-card class="part2" ref="monitoringCenterCard" />
      </div>
      <div class="right-part">
        <app-list-card
          class="part3"
          ref="appListCard"
          @showAppConfigDrawerEvent="handleShowAppConfigDrawerEvent"
          @deviceGatewayRows="handleGatewayRows"
        />
        <app-relation-card class="part4" ref="appRelationCard" />
      </div>
    </div>
  </div>
</template>

<script>
import GatewayTableCard from "./gateway-table-card";
import AppListCard from "./app-list-card";
import AppRelationCard from "./app-relation-card";
import MonitoringCenterCard from "./monitoring-center-card";
</script>

export default {
  components: {
    GatewayTableCard,
    AppListCard,
    AppRelationCard,
    MonitoringCenterCard,
  },
  //依赖注入传值
  provide() {
    return {
      newFoo: this.edgexGatewatDate
    }
  },
  data() {
    return {
      edgexGatewatDate: {
        deviceState: 0
      },
    }
  },
  methods: {
      handleGatewayTableRowClick(item) {
        this.edgexGatewatDate.deviceState = item.deviceState // 未启用时应用状态等禁用
        // console.log('this.edgexGatewatDate', this.edgexGatewatDate)
        if (this.selectedGatewayId === item.id) {
          return;
        }
        this.selectedGatewayId = item.id;
        this.$refs.appListCard.apiGetEdgeGatewayAppList(item.id);
        this.$refs.appRelationCard.apiGetEdgeGatewayRelate(item.id);
        this.$refs.monitoringCenterCard.apiGetDeviceProViewList(item.id);
    },
  }
}

子组件

<template>
  <div class="app-item-container">
    <div class="app-list-item">
      <div class="item-info">
        <div class="info-content">
          <div>{{ appName }}</div>
          <div>{{ createTime }}</div>
        </div>
        <el-button
          type="text"
          size="small"
          icon="el-icon-arrow-right"
          :disabled="newFoo.deviceState === 3"
        ></el-button>
        <div></div>
      </div>
    </div>
  </div>
</template>

<script>
import { GateWayStateKeyMap } from "@/config/gatewayStateMap";

export default {
  components: {},
  name: "app-list-item",
  props: {
    appName: { type: String, default: "" },
    createTime: { type: String, default: "" },
  },
  inject: ['newFoo'],
  data() {
    return {
      gatewayList: [],
      gateWayStateKeyOp: GateWayStateKeyMap,
    };
  },
};
</script>

posted on 2022-02-16 13:24  取个名字真wff  阅读(110)  评论(0编辑  收藏  举报