跳到主要内容

inject

2023年05月06日
柏拉文
越努力,越幸运

一、组合式


inject() 注入一个由祖先组件或整个应用 (通过 app.provide()) 提供的值。与注册生命周期钩子的 API 类似,inject() 必须在组件的 setup() 阶段同步调用。

1.1 语法

const value = inject('key');

const value = inject('key', 'default value'); // 注入基础数据

const value = inject('key', ()=> 'default value'); // 注入引用数据

const value = inject('key', ()=> {} , false); // 注入函数
  • key: 注入的 keyVue 会遍历父组件链,通过匹配 key 来确定所提供的值。如果父组件链上多个组件对同一个 key 提供了值,那么离得更近的组件将会“覆盖”链上更远的组件所提供的值。如果没有能通过 key 匹配到值,inject() 将返回 undefined,除非提供了一个默认值。

  • 默认值: 可选的,即在没有匹配到 key 时使用的默认值。它也可以是一个工厂函数,用来返回某些创建起来比较复杂的值。如果默认值本身就是一个函数,那么你必须将 false 作为第三个参数传入,表明这个函数就是默认值,而不是一个工厂函数。

1.2 通信

provideinject 如果绑定的是基础数据, 那么是非响应的provideinject 如果绑定的是响应式的对象,那么对象的 property 是可响应的

<template>
<div>
{{ a }}

<button @click="changeA(a+1)">父组件按钮</button>
<Child></Child>
</div>
</template>

<script setup lang="ts">
import { provide, reactive, ref } from "vue";
import Child from "./Child.vue"

const a = ref(0);
const changeA = (value: number)=>{
a.value = value;
}

const b = reactive({
a,
changeA,
});

provide('a',a.value);
provide('b',b);
</script>

二、选项式


inject 用于声明要通过从上层提供方匹配并注入进当前组件的属性。请注意,注入绑定并非响应式的。这是有意为之的一个设计。如果要注入的值是一个响应式对象,那么这个对象上的属性将会保留响应性。

2.1 语法

inject 选项应该是以下两种之一:

  • 一个字符串数组

  • 一个对象: 其 key 名就是在当前组件中的本地绑定名称,而它的值应该是以下两种之一:

    • 匹配可用注入的 key (string 或者 Symbol)

    • 一个对象:

      • from: 一个 key (string 或者 Symbol),用于匹配可用的注入

      • default: 用作候补值。和 props 的默认值类似,如果它是一个对象,那么应该使用一个工厂函数来创建,以避免多个组件共享同一个对象。如果没有供给相匹配的属性、也没有提供默认值,那么注入的属性将为 undefined

inject: ['a','b','state'],

inject: {
a: {
from: 'a',
default: 'XXX'
},
b: {
from: 'b',
default: 'XXX'
},
state:{
from: 'state',
default: ()=>{
return XXX
}
}
}

2.2 通信

provideinject 如果绑定的是基础数据, 那么是非响应的provideinject 如果绑定的是响应式的对象,那么对象的 property 是可响应的

<template>
<div>
<HelloWorld></HelloWorld>
<button @click="addNum">App 组件 增加 State.Num</button>
<button @click="addListItem">App 组件 增加 State.List</button>
</div>
</template>

<script>
import HelloWorld from "./HelloWorld.vue";

export default {
name: "App",
components: {
HelloWorld,
},
data() {
return {
state: {
num: 0,
list: [],
},
};
},
provide() {
return {
state: this.state,
addNum: this.addNum,
addListItem: this.addListItem
};
},
methods: {
addNum() {
this.state.num = this.state.num + 1;
},
addListItem(){
const item = this.state.num;
this.state.list.push(item)
}
},
};
</script>