vue3字典封装

562 阅读1分钟

前言

在日常开发中,我们避免不了使用字典,那么如何来优雅的使用字典呢,在这里我用vue插件的方式封装了一个字典,当然也可无缝转为hook形式,纯个人喜好,话不多说,直接上代码:

import { ref } from 'vue'

export default {
  install(app) {
    // 缓存字典数据
    const state = {}
    const map = new Map()
    const getDictData = (dictName, refObj) => {
      // 用promise模拟异步请求
      new Promise((resolve) => {
        setTimeout(() => {
          refObj.value = {
            1: '字典1',
            2: '字典2',
            3: '字典3',
          }
          resolve()
        }, 3000)
      }).then(() => {
        // 这里每次有异步请求都会触发事件,而我们的需求是当key存在才触发,所以这里加上 && 来做判断,更新ref的值
        map.get(dictName) && map.get(dictName)()
        // 字典已被缓存,可以放心移除记录,防止内存泄漏(箭头函数会被GC)
        map.delete(dictName)
      })
    }
    /**
     * 获取字典数据
     * @param {*} dictName
     * @param {*} key
     * @returns
     */
    const getDict = (dictName, key = null) => {
      const value = ref('')
      if (dictName in state) {
        if (key !== null) {
          value.value = state[dictName].value[key]
          return value
        }
        return state[dictName]
      } else {
        const refObj = ref({})
        state[dictName] = refObj
        getDictData(dictName, refObj)
        if (key !== null) {
          // 订阅事件,如果是批量订阅,那么可以选择数组,单个订阅且精准触发该事件的话,Map是更好的选择
          map.set(dictName, () => value.value = state[dictName].value[key])
          return value
        }
        return state[dictName]
      }
    }
    app.config.globalProperties.$dict = getDict
  }
}

使用方式

在main.js上导入,在vue实例在使用插件

image.png 在模板上使用

image.png 第一个参数是字典名称,第二个参数是该字典对应的key; 只传第一个参数,直接返回整本字典对象,就像:

image.png 传两个参数则返回对应字典key所映射的value:

image.png

image.png

在script下使用

image.png 也是ok的,大家可以复制印证下,如有错误请指出,共勉~