简单的Vue3字典管理插件

55 阅读1分钟

参考其它文章编写了一个简单的Vue3字典管理插件


import {ref} from 'vue'
import {listDictItem} from '@/api/system/dict.ts'

// 使用DEMO
// Script 使用
// const dictList = inject('dict').getDict('states')
// const dict = inject('dict').getDict('btdd','key')
// Template 使用
// <span>{{ $dict('btdd','key') }}</span>

export default {
    install(app) {
        const state = {}
        const map = new Map()
        const getDictData = async (dictName) => {
            try {
            // 替换为你的接口异步请求
                const res = await listDictItem({
                    dictType: dictName,
                    pageNum: 1,
                    pageSize: 1000,
                })
                state[dictName].value = res.list.map((item) => {
                    return {
                        label: item.dictName,
                        value: item.dictValue
                    }
                })
                // 触发所有订阅事件
                const callbacks = map.get(dictName)
                if (callbacks && Array.isArray(callbacks)) {
                    callbacks.forEach(callback => callback())
                }
            } finally {
                // 字典已被缓存,可以放心移除记录,防止内存泄漏(箭头函数会被GC)
                map.delete(dictName)
            }
        }
        
        /**
         * 获取字典数据
         * @param {*} dictName
         * @param {*} key
         * @returns
         */
        const getDict = (dictName, key = null) => {
            const value = ref('')
            // 如果数据已经加载完成,直接返回
            if (dictName in state) {
                if (key !== null) {
                    if (state[dictName].value.length > 0) {
                        value.value = state[dictName].value.find((item) => item.label === key)?.value
                    } else {
                        // 数据还在加载中,添加到订阅队列
                        // 利用数组处理多次并发订阅时后面订阅会覆盖前面订阅的问题
                        if (!map.has(dictName)) {
                            map.set(dictName, [])
                        }
                        map.get(dictName).push(() => {
                        // 根据异步获取的实际情况赋值
                            value.value = state[dictName].value.find((item) => item.label === key)?.value
                        })
                    }
                    return value
                } else {
                    return state[dictName]
                }
            } else {
                state[dictName] = ref([])
                getDictData(dictName).then(() => {
                    if (key !== null) {
                    // 根据异步获取的实际情况赋值
                        value.value = state[dictName].value.find((item) => item.label === key)?.value
                    }
                })
                if (key !== null) {
                    return value
                } else {
                    return state[dictName]
                }
            }
        }
        app.config.globalProperties.$dict = getDict
        app.provide('dict', {getDict})
    }

全局使用引入参考Vue3 插件使用文档