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

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

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

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

export default {
  namespaced: true,
  state: {
    types: {}
  },
  mutations: {
    ADD_TYPE: (state, params) => {
      state.types[params.type] = params.value;
    }
  }
}

Dict.js

/**
 * 字典,用以匹配后端字典
 */
export default class Dict {
  constructor(serve) {
    this.serve = serve;
    this.id = "dictValue";
    this.label = "dictLabel";
    this.isDict = true;
  }
}

Enum.js

/**
 * 枚举,用以匹配后端枚举
 */
export default class Enum {
  constructor(serve) {
    this.id = "code";
    this.label = "name";
    this.isEnum = true;
    this.serve = serve;
  }
}

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;
    }
  }
}

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")
}

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>

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

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

下面是使用方法

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

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")
}
属性
属性类型说明
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>
自定义插槽

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

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

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

<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>
默认插槽

用以自定义追加数据

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
浏览器不调用vue数据字典可能有以下几个原因: 1. 未正确引入Vue库:在使用Vue框架时,需要在HTML页面正确引入Vue库,否则浏览器无法识别和调用Vue相关的代码。 2. 数据字典未在Vue实例注册:Vue的数据字典通常通过Vue的data属性来定义和管理,然后在Vue实例进行注册。如果没有将数据字典注册到Vue实例,浏览器无法访问和调用它们。 3. 数据字典命名错误或作用域问题:可能是因为数据字典的命名与调用时的不一致,或者数据字典定义在Vue实例范围之外,导致浏览器无法正确调用。 4. 调用方式错误:在模板使用数据字典时,应该通过Vue提供的指令或表达式来调用和显示数据字典的值。如果调用方式不正确,浏览器可能无法正确显示数据字典的值。 为了解决这个问题,可以按照以下步骤进行检查和修复: 1. 确保正确引入Vue库:在HTML页面检查是否正确引入Vue库的脚本文件,例如在头部或底部添加<script src="vue.js"></script>。 2. 检查数据字典的注册和使用:确认数据字典是否在Vue实例正确注册,并在需要使用的地方正确调用。可以使用Vue开发者工具等调试工具查看数据字典的值是否正确。 3. 检查命名和作用域:确保数据字典的命名无误且与调用时一致,并且在正确的作用域内定义和注册数据字典。 4. 学习和使用正确的调用方式:学习和使用Vue的指令、表达式等方式来调用和显示数据字典的值,确保调用方式正确。 总结:浏览器不调用vue数据字典可能是由于引入Vue库失败、数据字典未注册、命名错误、作用域问题或调用方式错误等原因造成。通过检查和修复这些可能导致问题的地方,可以解决浏览器不调用vue数据字典的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

会功夫的李白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值