provide / inject 遇到的麻烦(vue3)

150 阅读1分钟

不知道如何写类型

文档解释:为 provide / inject 标注类型

假设要provide的数据是:

{
  fun: async () => (),
  loading: true,
  search: false,
}

用的是setup的语法糖:

<script lang="ts" setup>
    const fun = ...
    ....
    provide(
        'xxxxx',
        {
          fun,
          loading: loading.value,
          search: false
        }
    );
        
</script>

怎么给类型呢?又怎么设定inject的名字对应的是'xxxxx'呢?

1、新建一个数据的类型
// type.ts

export interface xxDataType {
  fun: () => Promise<void>;
  loading: boolean;
  search: boolean;
}

2、新建一个'xxxxx' key
// symbol.ts
import { InjectionKey } from 'vue';
import { xxDataType } from './custom';

export const XXProvide: InjectionKey<xxDataType> = Symbol();

3、就可以用了,inject只要写入XXProvide,就必须要匹配类型xxDataType
provide(
    XXProvide,
    {
      fun,
      loading: loading.value,
      search: false
    }
);

// 子孙组件
const xx = inject(XXProvide);

无法监听到provide方数据的变化!

查了一下文档,说明要结合computed使用:和响应式数据配合使用

provide(
  XXProvide,
  computed(() => (
    {
      fun,
      loading: downloading.value,
      search: false
    }
  )
);

类型就要加一下ComputedRef:

// symbol.ts
export const XXProvide: InjectionKey<ComputedRef<xxDataType>>  = Symbol();

而且不能.value解构取值等,会失去响应式:

const { fun, loading, search } = inject(XXProvide).value; // 不行

const xx = inject(XXProvide).value // 也不行

const xx = inject(XXProvide) // 行

// 标签上使用:省.value
<div if="xx?.value.search" /> // 不行
<div if="xx?.search" /> // 行

inject可以设置默认值,防御取到初始值undefined

const xx = inject(
    XXProvide,
    {
       fun: async() => {},
       loading: true,
       search: true
    }
);

// 或者用 可选链 符号:
xx?.fun?.();