把computed和inject的功能组合起来,用于对注入的数据进行响应式计算
能够在依赖注入inject的时候,进一步对数据进行加工
demo
context.ts
像普通provide/inject定义的一样,定义数据类型,内容如下:
ts
import { InjectionKey } from "vue";
interface Item{
key:number,
value:string
}
export const ArrayKey:InjectionKey<Item[]> = Symbol('symbol-key')
在父组件像普通provide一样,提供数据
vue
<template>
<h1>Parent父级节点</h1>
<div>{{array }}<button @click="handleChange">改变</button></div>
<hr>
<Childer></Childer>
</template>
<script setup lang="ts">
import { ref, provide } from 'vue'
import Childer from './components/Childer.vue';
import { ArrayKey } from './components/context';
const array = ref([
{
key:1,
value:'苹果'
},
{
key:2,
value:'香蕉'
}
])
provide(ArrayKey, array.value)
function handleChange () {
array.value[0].value = '橘子'+Math.random()
}
</script>
在后代组件中,用computedInject()
代替普通的inject()
vue
<template>
<h1>这是子组件</h1>
{{ fooArr }}
</template>
<script lang="ts" setup>
import { inject, watchEffect } from 'vue';
import {computedInject} from '@vueuse/core'
import {ArrayKey } from './context';
const fooArr = computedInject(ArrayKey, (source) => {
if (!source) {
return []
}
const arr = [...source]
arr.unshift({
key:0,
value:'水果'
})
return arr
});
</script>
api参数
1、默认值
和vue的inject()
一样,支持3个参数
ts
// 源码如下
export function computedInject(key, options, defaultSource, treatDefaultAsFactory) {
source = inject(key, defaultSource, treatDefaultAsFactory) as T
}
可以看出computedInject()
的第1/3/4参数是原样传给vue的inject()
而vue的inject()
参数可以看官网
2、第2个参数
第2个参数可以是一个函数,也可以是一个含有 {get(){}, set(){}}
的对象
ts
const result = computedInject(ArrayKey, {
get (neVal) {
return []
},
set (neVal) {
}
});
源码
ts
// key,defaultSource,treatDefaultAsFactory 原样传给
export function computedInject(key,options,defaultSource,treatDefaultAsFactory) {
let source = inject(key)
if (defaultSource)
source = inject(key, defaultSource)
if (treatDefaultAsFactory)
source = inject(key, defaultSource, treatDefaultAsFactory)
if (typeof options === 'function') {
return computed(ctx => options(source, ctx))
}
else {
return computed({
get: ctx => options.get(source, ctx),
set: options.set,
})
}
}