封装 Antd中Modal对话框内提交表单组件,开发效率翻倍

业务背景:

在业务管理系统的项目中,几乎每个页面都会出现增、删、改、提交等对话框,如下图所示:
在这里插入图片描述

如果每个弹出的对话框,都去拷贝a-tree-select、a-select、a-input、a-radio-group等表单项代码片段,重写add()、edit()、submit()、close()等方法;这会导致开发效率很低,因此,本次文档将描述如何封装常用的表单对话框,以备下次开发复用,极大提高工作效率,尽早下班。

1、首先引入对话框Modal的代码框架

该适合基本使用的代码框架包含两个部分:HTML代码块,JS代码块;其中JS代码块包含对话框宽度、标题自定义传参,对象赋值方法,增改接口,增改对应的函数。

<template>
<a-modal :title="title" :width="width" :visible="visible" :confirmLoading="confirmLoading" @ok="handleOk" @cancel="handleCancel" cancelText="关闭">
 将注入表单详细内容
  </a-modal>
</ template >
<script>
import pick from 'lodash.pick';
import { addDict, editDict} from '@/api/api';

export default {
    name: 'FormModal',
    props: {
      width:{
        type:Number,
        default: 600
      },
      title:{
        type:String,
        default: ‘操作’
      },
      labelCol:{
        type:Object,
        default: () => { 
          return{
            xs: { span: 24 },
            sm: { span: 5 }
          }
        }
      },
      wrapperCol:{
        type:Object,
        default: () => { 
          return{
            xs: { span: 24 },
            sm: { span: 16 }
          }
        }
      }
    },
    data () {
        return {
            visible: false,
            model: {},
            confirmLoading: false,
            form: this.$form.createForm(this)
         };
    },
    created () {},
    methods: {
        add () {
            this.edit({});
        },
        edit (record) {
            this.form.resetFields();
            this.model = Object.assign({}, record);
            this.visible = true;
            this.$nextTick(() => {
                this.form.setFieldsValue(
pick(this.model, 'dictName', 'dictCode', 'description'));
            });
        },
        // 确定
        handleOk () {
            const that = this;
            // 触发表单验证
            this.form.validateFields((err, values) => {
                if (!err) {
                    that.confirmLoading = true;
                    values.dictName = (values.dictName || '').trim();
                    let formData = Object.assign(this.model, values);
                    let obj;
                    console.log(formData);
                    if (!this.model.id) {
                        obj = addDict(formData);
                    } else {
                        obj = editDict(formData);
                    }
                    obj
                        .then(res => {
                            if (res.success) {
                                that.$message.success(res.message);
                                that.$emit('ok');
                            } else {
                                that.$message.warning(res.message);
                            }
                        })
                        .finally(() => {
                            that.confirmLoading = false;
                            that.close();
                        });
                }
            });
        },
        // 关闭
        handleCancel () {
            this.close();
        },
        close () {
            this.$emit('close');
            this.visible = false;
        }
    }
};
</script>
2、封装出单项表单组件,根据不同的传参确定表单项的输入类型

组件的详细入参如下:

  props: {
    itemOptions: {
      // 控件的基本参数
      type: Object,
      default: function () {
        return {
          type: 'text', // 控件类型
          defaultValue: '', // 默认值
          label: '控件名称', // 控件显示的文本
          value: '', // 控件的值
          size: '', // 控件大小
          placeholder: '' // 默认控件的空值文本
        };
      }
    }
  }

举个例子,当传入参数的控件类型type为text,组件内部的代码为:

    <template v-if="itemOptions.fieldName && itemOptions.type === 'text'">
        <a-form-item :label-col="labelCol" :wrapper-col="wrapperCol" :label="itemOptions.labelText">
          <j-input
           style="width: 100%"
            :size="itemOptions.size ? itemOptions.size : 'default'"
            :type="itemOptions.type ? itemOptions.type : 'like'"
            v-decorator="[
              itemOptions.fieldName,
              { 
                initialValue: itemOptions.defaultValue ? itemOptions.defaultValue : '',
                rules: Array.isArray(itemOptions.rules) && itemOptions.rules.length > 0 ? itemOptions.rules : [] 
              }
            ]"
            :placeholder="itemOptions.placeholder? itemOptions.placeholder :`请输入${itemOptions.labelText}`"
            allowClear
          />
        </a-form-item>
    </template>

3.将封装的单项表单组件引入modal对话框内容部分
  <a-modal :title="title" :width="width" :visible="visible" :confirmLoading="confirmLoading" @ok="handleOk" @cancel="handleCancel" cancelText="关闭">
    <a-spin :spinning="confirmLoading">
      <a-form :form="form" ref="form">
         <template v-for="(item,index) in fieldOptions" :label-col="labelCol" :wrapper-col="wrapperCol" :label="item.labelText">
            <field-render :key="index" :itemOptions="item"/>
         </template>
      </a-form>
    </a-spin>
  </a-modal>

4、根据业务需求传入相应的fieldOptions参数即可,其余代码均可复用

之后的每一次调用只需要修改fieldOptions的内容就可以了,其他内容可保持不变,大大提高了生成对话框表单的效率。

举个fieldOptions赋值的例子:

computed: {
  fieldOptions(){
        return [
          {
            type: 'treeSelect', 
            labelText: '归属机构', 
            fieldName: 'orgId',
            treeData: this.selectData,
            rules: this.validatorRules.empty
          },
          {
            type: 'text', 
            labelText: '项目名称', 
            fieldName: 'projectName',
            rules: this.validatorRules.empty
          },
          {
            type: 'radio',
            labelText: '状态',
            fieldName: 'status',
            options: this.dict.status,
          }
        ]
      }
    }

最后,值得一提的是,上述代码块能将我一小时的开发时长缩短至20分钟,开发效率得以提升,后续我还会持续发布一系列封装常用功能组件的文章,并分享出来,希望能给陷入重复功能开发人士一点启发,可以早点下班回家,快乐生活~

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值