coder-common-thin-frontend/src/hooks/useDict.ts

76 lines
2.1 KiB
TypeScript

import type { MaybeRef } from 'vue'
import { computed, unref, watch } from 'vue'
import { toSelectOptions } from '@/utils/dict'
import { useDictStore } from '@/store'
import type { DictDataOption } from '@/service/api/system/dict'
interface UseDictOptions {
/** 是否在创建时立即加载,默认为 true */
immediate?: boolean
/** 监听类型变化时是否强制刷新 */
force?: boolean
}
export function useDict(dictTypes: MaybeRef<string[] | undefined>, options: UseDictOptions = {}) {
const dictStore = useDictStore()
const normalizedTypes = computed(() => {
const value = unref(dictTypes) ?? []
return value.filter((item): item is string => Boolean(item))
})
const load = async (force = false) => {
const types = normalizedTypes.value
if (!types.length)
return
await dictStore.fetchDicts(types, force)
}
watch(
normalizedTypes,
(types) => {
if (!types.length)
return
void dictStore.fetchDicts(types, options.force ?? false)
},
{ immediate: options.immediate ?? true },
)
const dictOptions = computed<Record<string, DictDataOption[]>>(() => {
const result: Record<string, DictDataOption[]> = {}
normalizedTypes.value.forEach((type) => {
result[type] = dictStore.getDictOptions(type)
})
return result
})
const isLoading = computed(() => normalizedTypes.value.some(type => dictStore.isLoading(type)))
const getDictLabel = (dictType: string, value: unknown, fallback?: string) =>
dictStore.getDictLabel(dictType, value, fallback)
const getDictOption = (dictType: string, value: unknown) =>
dictStore.getDictOption(dictType, value)
const getSelectOptions = (dictType: string) => toSelectOptions(dictStore.getDictOptions(dictType))
const reload = async (targetTypes?: string[]) => {
const types = targetTypes && targetTypes.length ? targetTypes : normalizedTypes.value
if (!types.length)
return
await dictStore.fetchDicts(types, true)
}
return {
dictOptions,
isLoading,
load,
reload,
getDictLabel,
getDictOption,
getSelectOptions,
}
}