通过返回的key值匹配字典中的value值
需求
页面中上面搜索项有获取字典枚举接口,table表格中也有根据key匹配字典中的value
方案一

需要做到的要求
- 这里上面下拉列表是一个组件获取的字典,下面也是通过字典匹配,所以尽量统一封装一个函数,每个组件保证最少变动
 - table表格中如果filters中更改,会获取多次接口,—使用闭包让只获取一次接口,节省性能
 - filter中又是必须同步函数,异步函数报错,所以不能使用async,await
 - 最好请求接口之后存储起来下次直接拿不用请求了
 
综上
utils/dictionary.js
import { getDicValue } from '@/api/systemManage'
import store from '@/store'
/**
 * 获取字典数据
 * @param {Boolean} hasAllOption 是否包含全部选项
 */
export function getDicValueList(dictClassCode, hasAllOption = true) {
  const dictionaryCache = store.state.dictionary.dictionaryCache || {}
  return new Promise((resolve, reject) => {
    let optionList = []
    if (dictionaryCache[dictClassCode]) {
      const dicList = JSON.parse(JSON.stringify(dictionaryCache[dictClassCode]))
      if (hasAllOption) {
        optionList = [ { value: '', label: '全部' }, ...dicList]
      } else {
        optionList = [...dicList]
      }
      resolve(optionList)
    } else {
      getDicValue(dictClassCode).then(response => {
        console.log('字典调用', dictClassCode)
        const dicList = response.value || []
        store.dispatch('dictionary/setDictionaryCache', { key: dictClassCode, value: dicList })
        if (hasAllOption) {
          optionList = [ { value: '', label: '全部' }, ...dicList]
        } else {
          optionList = [...dicList]
        }
        resolve(optionList)
      }).catch(error => {
        reject([])
      })
    }
  })
}
/**
 * 获取字典数据并返回一个闭包函数
 * @param {string} dictClassCode 字典类代码
 * @param {string} noTitle 默认值,当找不到匹配项时返回
 * @returns {Promise<Function>} 返回一个闭包函数,该函数可以根据 value 获取 label
 */
export async function getDicValueName(dictClassCode, noTitle = "--") {
  try {
    const response = await getDicValueList(dictClassCode, false)
    const listData = response || []
    return (value) => {
      let label = noTitle
      listData.some(item => {
        if (item.value === value) {
          label = item.label
          return true
        }
      })
      return label
    }
  } catch (err) {
    console.error(err)
    return (value) => noTitle
  }
}
 
下拉框组件
created () {
    this.getOptionLists()
  },
getOptionLists() {
      if (this.dictClassCode) {
        getDicValueList(this.dictClassCode).then(res => {
          this.optionLists = res
        })
      } else {
        this.optionLists = this.options
      }
    },
 
table组件中
<span>{{ filterStateName(scope.row.state) }}</span>
import { getDicValueName } from '@/utils/dictionary'
created() {
    this.initDictionary()
  },
methods: {
async initDictionary() {
      try {
        this.filterStateName = await getDicValueName('DC_DICTIONARY_STATE')
      } catch (error) {
        console.error('Failed to fetch dictionary:', error)
        this.filterStateName = (value) => '--'
      }
    },
   }
 
问题: 但是这种因为一进页面这两个组件都是去获取字典,所以还是从接口拿的数据,会调用两次接口
方案二(建议)
方案:接下来优化可以通过路由导航预加载,先获取字典之后,在加载页面
 router.js
// 预加载字典
export function preloadDictionary(dictClassCodeList) {
  const pList = []
  dictClassCodeList.forEach(dictClassCode => {
    const p = getDicValueList(dictClassCode)
    pList.push(p)
  })
  return Promise.all(pList)
}
// 预加载字典
router.beforeEach((to, from, next) => {
  if(to.meta && to.meta.dictClassCodeList&& to.meta.dictClassCodeList.length > 0) {
    preloadDictionary(to.meta.dictClassCodeList).then(res => {
      next()
    })
  } else {
    next()
  }
})
 
总结:其实这里都可以规定直接预加载字典,到页面直接使用加载后的字典,注册个全局filters就行,根本不用上面那些,先都记录上,后期根据需求灵活应用吧
