• 在 Vue 项目中添加字典翻译工具(二)


    封装字段翻译组件,可以格式化字典、枚举、字段
    优点: 使用简单,一次配置多次使用,缓存降低后端请求次数,扩展性强

    没有缓存时造成单页面多次请求解决方法:axios添加缓存请求,防止多次请求,单页面多个同一组件造成多次请求解决方案

    store 的 fieldFormat.js(这里用的store的modules)

    export default {
      namespaced: true,
      state: {
        types: {}
      },
      mutations: {
        ADD_TYPE: (state, params) => {
          state.types[params.type] = params.value;
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Dict.js

    /**
     * 字典,用以匹配后端字典
     */
    export default class Dict {
      constructor(serve) {
        this.serve = serve;
        this.id = "dictValue";
        this.label = "dictLabel";
        this.isDict = true;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Enum.js

    /**
     * 枚举,用以匹配后端枚举
     */
    export default class Enum {
      constructor(serve) {
        this.id = "code";
        this.label = "name";
        this.isEnum = true;
        this.serve = serve;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Field.js

    /**
     * 字段,用以匹配后端字段
     */
    export default class Field {
      constructor(serve, id, label, method, dataField) {
        this.serve = serve;
        this.id = id;
        this.label = label;
        if (method) {
          this.method = method;
        }
        if (dataField) {
          this.dataField = dataField;
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    formatOptions.js

    import * as vehicleTypeService from "@/api/bayonet/vehicleType";
    import Enum from "./Enum";
    import Dict from "./Dict";
    import Field from "./Field";
    
    /**
     * 字段格式化组件参数
     *
     * @param serve 请求地址或请求方法或枚举类型,请求方法可以是api中的,必须是Function: () => Promise格式
     * @param id 请求后的数据列表字段,用于匹配那一条数据
     * @param label 请求后的数据列表字段,用于自动格式化字段
     * @param method 请求方式,默认get
     * @param dataField 请求后的data字段,默认data
     * @param isEnum 是否枚举,开启将请求后端枚举
     * @param isDict 是否字典,开启将请求后端字典
     */
    export default {
      // 车辆类型
      vehicleType: new Field(vehicleTypeService.getList, "vehicleTypeId", "name"),
      // 审批状态
      approvalStatusEnum: new Enum("com.yunku.project.entryApplication.enums.ApprovalStatus"),
      // 申请类型
      applicationTypeEnum: new Enum("com.yunku.project.entryApplication.enums.ApplicationType"),
      vehicle_enter_status: new Dict("vehicle_enter_status")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    FieldFormat.vue

    <template>
      <div>
        <template v-if="label && data && !hasSlot">{{ data[label] }}template>
        <slot>slot>
        <slot name="format" :data="data">slot>
        <slot name="list" :list="list">slot>
      div>
    template>
    
    <script>
    import request from '@/utils/request'
    import {getDicts as getDicts} from '@/api/system/dict/data';
    import formatOptions from "./formatOptions";
    
    export default {
      name: "FieldFormat",
      props: {
        value: [String, Number],
        type: String,
        params: Object
      },
      data() {
        return {
          enumUrl: 'common/utility/getEnumList',
          data: undefined,
          list: [],
          serve: undefined,
          id: undefined,
          label: undefined,
          method: 'get',
          dataField: 'data',
          isEnum: false,
          isDict: false
        }
      },
      computed: {
        fieldFormats() {
          // 获取vuex中缓存的数据
          return this.$store.state.fieldFormat.types;
        },
        hasSlot() {
          // 判断有没有插槽(默认插槽除外)
          return (this.$scopedSlots && (!!this.$scopedSlots.list || !!this.$scopedSlots.format))
            || (this.$slots && (!!this.$slots.list || !!this.$slots.format));
        }
      },
      watch: {
        type: {
          handler(n) {
            // 类型改变时重新获取数据
            if (n) {
              this.getData();
            }
          }
        },
        value: {
          handler(n) {
            // 值改变时重新解析
            if (n) {
              this.format();
            }
          }
        }
      },
      methods: {
        /**
         * 解析
         */
        format() {
          // 在列表中查找对应数据
          const list = this.list;
          if (list && list.length > 0) {
            this.data = list.find(datum => String(datum[this.id]) === String(this.value));
          }
        },
        /**
         * 获取参数
         * @returns {string|*}
         */
        getOption() {
          // 根据type获取option
          const option = formatOptions[this.type];
          // 赋值属性
          Object.assign(this.$data, option);
          return option.serve;
        },
        /**
         * 获取数据
         */
        getData() {
          const method = this.method;
          const serve = this.getOption();
    
          // 如果vuex中有当前类型缓存,则取缓存
          if (this.fieldFormats[this.type]) {
            this.list = this.fieldFormats[this.type];
            this.format();
            return;
          }
    
          if (serve instanceof Function) {
            // 如果serve类型为Function,则直接调用取值
            serve().then(res => {
              this.relRes(res);
            });
          } else {
            if (this.isDict) {
              this.relDict();
            } else if (this.isEnum) {
              this.relEnum();
            } else {
              const query = {
                url: serve,
                method: method,
              }
              // get请求和post请求的参数不一样
              query[this.method === 'get' ? 'params' : 'data'] = this.params;
              // 请求
              request(query).then(res => {
                this.relRes(res);
              });
            }
          }
        },
        /**
         * 解析枚举
         */
        relEnum() {
          request({
            url: this.enumUrl,
            method: 'get',
            params: {
              enumType: this.serve
            }
          }).then(res => {
            this.relRes(res);
          })
        },
        /**
         * 解析字典
         */
        relDict() {
          getDicts(this.serve).then(res => {
            this.relRes(res);
          });
        },
        /**
         * 解析结果
         */
        relRes(res) {
          let list = this.list = res[this.dataField];
    
          this.$store.commit("fieldFormat/ADD_TYPE", {
            type: this.type,
            value: list
          });
    
          this.format();
        }
      },
      created() {
        this.getData();
      }
    }
    script>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165

    main.js添加,可全局使用,不需要页面单独引入

    import FieldFormat from "@/components/FieldFormat";
    Vue.component('FieldFormat', FieldFormat)
    
    • 1
    • 2

    下面是使用方法

    字段格式化工具(可以格式化字典、枚举、字段)

    1. 添加参数

    src/components/FieldFormat/formatOptions.js 中,添加格式化参数

    你可以直接使用 JSON 格式来添加参数,也可以使用已定义的 class

    export default {
      // 车辆类型
      vehicleType: {
        serve: vehicleTypeService.getList,
        id: "vehicleTypeId",
        label: "name",
        method: 'get',
        dataField: 'data'
      },
      // 审批状态
      approvalStatusEnum: new Enum("com.yunku.project.entryApplication.enums.ApprovalStatus")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    属性
    属性类型说明
    serveString 或 Function请求地址或请求方法或枚举类型,请求方法可以是api中的,必须是Function: () => Promise格式
    idString请求后的数据列表字段,用于匹配那一条数据
    labelString请求后的数据列表字段,用于自动格式化字段
    methodString请求方式,默认get
    dataFieldString请求后的data字段,默认data
    isEnumBoolean是否枚举,开启将请求后端枚举
    isDictBoolean是否字典,开启将请求后端字典
    class
    属性类型说明
    Enum枚举用以匹配后端枚举
    Dict字典用以匹配后端字典
    Field字段用以匹配后端字段
    2. 使用
    格式化

    在需要格式化的地方,使用组件 field-format,value为已知数据值, type 为 formatOptions 中添加的名称,另外还有 params 字段用于请求自定义传参

    <field-format :value="form.vehicleType" type="vehicleType">field-format>
    
    • 1
    自定义插槽

    可以使用插槽实现更多场景的功能,如

    <field-format :value="form.vehicleType" type="vehicleType">
      <template #format="{data}">{{ data.name }}template>
    field-format>
    
    • 1
    • 2
    • 3
    遍历

    或者获取所有列表,用于遍历

    <field-format type="vehicleType">
        <template #list="{list}">
          <el-select v-model="form.vehicleType">
            <el-option
              v-for="item in list"
              :label="item.name"
              :value="item.vehicleTypeId"
              :key="item.vehicleTypeId"
            >el-option>
          el-select>
        template>
      field-format>
    el-form-item>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    默认插槽

    用以自定义追加数据

  • 相关阅读:
    面试必备:一线大厂Redis缓存设计规范与性能优化
    OwnCloud个人云盘搭建方法
    我31岁,做美工一月8K,后面我该咋办?
    LAMP平台的搭建
    Java高级工程师常见面试题(答案)
    数据分析---matplotlib2
    【云原生之Docker实战】使用docker部署nginx-proxy-manager-zh反向代理工具
    机器视觉中的工业光源选择技巧
    D. Reverse Sort Sum(思维 + 差分 + 树状数组)
    嵌入式linux相机 框图
  • 原文地址:https://blog.csdn.net/jl15988/article/details/133157861