字典项相关应用

117 阅读2分钟

字典项,自动加载字典项数据及对其进行翻译、配置写成 options中的插件进行使用

在项目中,我们可能会重复的使用字典项,对其进行请求、数据回显等,就会涉及到数据的加载、转换(翻译)及其配置信息的修改,下面的代码为解决这个问题
将字典项以插件的形式进行配置,能够实现自动加载相应数据、是否缓存、翻译数据、信息配置

字典项插件

// 定义处理字典项的插件

import Vue from "vue";

/**
 * 模拟后端接口,使用时换成后端接口函数即可
 * @param {*} param
 * @returns
 */

function ajaxGetDictItems() {
  const res = {
    code: 200,
    msg: "操作成功",
    result: [
      {
        value: "1",

        label: "篮球"
      },
      {
        value: "2",

        label: "羽毛球"
      },
      {
        value: "3",

        label: "乒乓球"
      },

      {
        value: "4",

        label: "足球"
      }

    ]

  };
  return Promise.resolve(res);
}


export class DictMeta {
  constructor(options) {
    this.type = options.type;
    this.request = options.request || ajaxGetDictItems;
    this.labelField = options.labelField || "label";
    this.valueField = options.labelField || "value";
  }
}

/**
 *
 * @param {*} dict
 * @param {*} dictMeta
 * @returns
 */
function loadDict(dict, dictMeta, cache) {
  // 是否需要缓存,如果需要缓存,该字典项已经请求过了,则不再发送请求,直接从 static里面拿取
  if ((dict.constructor.cacheTypes.find(item => item === dictMeta.type) && cache)) {
    // 使用定时器,因为下面的请求部分是使用 promise 请求,为异步代码后执行
      setTimeout(() => {
        // 设置数据的时候,直接使用 静态属性里面的值
        Vue.set(dict.dictOptions, [dictMeta.type], dict.constructor.cacheDictOptions[dictMeta.type]);
        Vue.set(dict.dictMaps, [dictMeta.type], dict.constructor.cacheDictMaps[dictMeta.type]);
      },0)
  } else {
    if(cache){
      dict.constructor.cacheTypes.push(dictMeta.type);
    }
    return dictMeta.request(dictMeta.type)
      .then(res => {
        if(cache){
          // 给 静态属性赋值
          dict.constructor.cacheDictOptions = {
            [dictMeta.type]: res.result
          }
          Vue.set(dict.dictOptions, [dictMeta.type], res.result);
          let dictMaps = {}
          // 将字典项变成键值对的形式,方便翻译的时候使用
          res.result.forEach(item => {
            dictMaps[item[dictMeta.valueField]] = item[dictMeta.labelField]
            Vue.set(dict.dictMaps[dictMeta.type], item[dictMeta.valueField], item[dictMeta.labelField]);
          });
          // 给静态属性赋值
          dict.constructor.cacheDictMaps = {
            [dictMeta.type] : dictMaps
          }
        } else {
          console.log('无缓存');
          Vue.set(dict.dictOptions, [dictMeta.type], res.result);
          res.result.forEach(item => {
            Vue.set(dict.dictMaps[dictMeta.type], item[dictMeta.valueField], item[dictMeta.labelField]);
          });
        }
      });
  }
}

class Dict {
  // 静态属性,存储缓存的数据
  static cacheTypes = []
  static cacheDictOptions = {};
  static cacheDictMaps = {};

  constructor() {
    this.owner = null;
    this.dictMaps = {};
    this.dictOptions = {};
    this.types = [];
    this._dictMetas = [];
  }
  // 初始化的时候,接收code,是否缓存还有配置项
  init(options, cache, otherConfig) {
    const promise = [];
    this.types = options;
    this._dictMetas = [];
    options.forEach(code => {
      Vue.set(this.dictMaps, code, {});
      Vue.set(this.dictOptions, code, []);
      const meta = new DictMeta({ type: code, config: otherConfig });
      this._dictMetas.push(meta);
      promise.push(loadDict(this, meta, cache));
    });
    return Promise.all(promise);
  }
}  

/**
 *
 * @param {*} Vue
 * @param {*} options
 */
function DataDictFn(Vue, cache = true, otherConfig) {
  Vue.mixin({
    data() {
      // 判断options上是否有挂载的dict并且dict是数组的形式
      if (!this.$options.dicts || !Array.isArray(this.$options.dicts)) {
        return {};
      }
      // 对上面的类进行赋值
      const dict = new Dict();
      dict.owner = this;
      return {
        dict
      };
    },
    created() {
      if (!(this.dict instanceof Dict)) {
        return;
      }
      this.dict.init(this.$options.dicts, cache, otherConfig)
        .then(() => {
          this.$emit("dict-ok", this.dict);
        });
    }
  });
}

export default DataDictFn;

在main.js中引入


import Dict from ./dict
// 在使用的时候可以传入配置项,第二个参数为 cache 默认为true,使用缓存,第三个参数为otherConfig 根据// 不同的字典项的 text,value 键来进行修改配置
Vue.use(Dict)

在项目中使用

<template>
</template>
<script>
// 直接加上字典项code即可
// 数据挂在到相应的 dict.dictOptions.test_code(最后为相应的code),翻译数据为 dict.dictMaps.test_code
dicts:["test_code"]
</script>

记录在项目中遇到的情况及解决方案,杀国