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>