美文网首页
封装 el-form

封装 el-form

作者: McDu | 来源:发表于2020-10-23 16:03 被阅读0次
     <el-form :inline="true" :model="form">
        <el-form-item label="目的地">
            <el-input v-model="form.arrive" placeholder="目的地"></el-input>
        </el-form-item>
        <el-form-item label="产品名称">
            <el-input v-model="form.enProductId" placeholder="产品名称"></el-input>
        </el-form-item>
        <el-form-item label="产品ID">
            <el-input v-model="form.productTitle" placeholder="产品ID"></el-input>
        </el-form-item>
        <el-form-item>
            <el-button type="primary" @click="queryList(1)">搜索</el-button>
        </el-form-item>
    </el-form>
    

    code inline

    1. 配置字段:根据 type 字段配置,比如 text、input、number、select、textarea、date、button 等。
    export const formField = [
        {
            label: '纯文本:',
            value: 'text',
            type: 'text'
        },
        {
            label: '普通输入框:',
            value: 'input_normal_test',
            type: 'input',
            placeholder: '不能为空',
            rules: R.inputNotEmpty({label: '订单号'})
        },
        {
            label: '字数限制:',
            value: 'input_numlimit_test',
            type: 'input',
            placeholder: '最多 5 个字',
            rules: [R.inputNotEmpty({label: '产品名称'}), getRule({rule: 'max', range: [5]})]
        },
        {
            label: '选择框:',
            value: 'select_test',
            type: 'select',
            options: selectOption
        },
        {
            type: 'slot',
            label: 'Slot 测试:',
            value: 'hahaha'
        },
        {
            label: '日期时间:',
            value: 'date_test',
            type: 'date',
            dateType: 'datetime',
            valueFormat: 'yyyy-MM-dd hh:mm:ss',
            rules: R.chooseNotEmpty(),
            pickerOptions: {
                disabledDate(time) {
                    return time.getTime() < Date.now() - 24 * 60 * 60 * 1000;
                }
            }
        },
        {
            label: '数字:',
            value: 'number_test',
            type: 'number',
            placeholder: '请输入数字',
            suffix: '小时',
            rules: [R.inputNotEmpty({label: '数字'}), R.intNumber()]
        },
        {
            label: '文本域:',
            value: 'textarea_test',
            type: 'textarea',
            rules: R.inputNotEmpty()
        },
        {
            text: '提交',
            type: 'button',
            event: 'submit'
        },
        {
            text: '重置',
            type: 'button',
            event: 'reset',
            styleType: 'defalut'
        }
    ];
    
    1. 表单项校验。内置 inputNotEmpty、chooseNotEmpty、intNumber,可以使用 getRule 方法根据自定义规则校验,比如 最大值、最小值、整数、中文、字符串等。
    // {0} 代表表单字段名, {1} {2} 代表分别代表验证条件 range[0] range[1]
    const errors = {
        notEmpty: '请输入{0}',
        max: '{0}最多为 {1} 个字符',
        min: '{0}最小为 {1} 个字符',
        fixedNum: '请输入{1}个字符',
        length: '{0}的长度在 {1} 到 {2} 个字符',
        number: '{0}必须是数字',
        intNum: '{0}必须是整数',
        numRange: '请输入{1}~{2}之间的数字',
        floatNum: '{0}必须是整数或最多两位小数',
        string: '{0}必须是字母或者数字',
        noChinese: '{0}不能为中文',
        chinese: '{0}必须为中文'
    };
    
    const methods = {
        notEmpty: v => v || v === 0,
    
        min: (v, arr) => v.length >= arr[0],
    
        max: (v, arr) => v.length <= arr[0],
    
        fixedNum: (v, arr) => v.length === arr[0],
    
        length: (v, arr) => arr[0] <= v + '' && v + '' <= arr[1],
    
        number: v => /^\d+(\.\d+)?$/.test(v),
    
        intNum: v => /^\d*$/.test(v),
    
        numRange: (v, arr) => {
            if(!v) {
                return true;
            }
    
            if (!methods.number(v)) {
                return false;
            }
    
            if(v < arr[0] || v > arr[1]) {
                return false;
            }
            return true;
        },
    
        floatNum: v => /^\d+(\.\d{1,2})?$/.test(v),
    
        string: v => /^[a-zA-Z0-9]*$/.test(v),
    
        chinese: v => /[\u4e00-\u9fa5]/.test(v),
    
        noChinese: v => !/[\u4e00-\u9fa5]/.test(v)
    };
    
    /**
     * @description: 生成 rules
     * @param {Object}
     * * @param {String} rule 要使用的规则名称
     * * @param {Array} range 规则数组
     * * @param {String} trigger 触发条件
     * * @param {String} label 表单字段名
     * * @param {Boolean} required 是否必填
     * * @return {Object} {required, validator, trigger, message?, type?}
     */
    export const getRule = ({rule, range, trigger = 'blur', label = '', required = true, errMsg = ''}) => {
        let validator,
            cRule = methods[rule],
            cError = errMsg || errors[rule];
    
        const result = {
            required,
            trigger
        };
    
        if (cRule) {
            validator = (rule, val, cb) => {
                // 校验通过:
                // 1. 必填,val 存在 && 符合 rule
                // 2. 非必填,val 存在 && 符合 rule
    
                const passRule = cRule(val, range);
                let valid = passRule;
    
                if(required) {
                    if(val && passRule) {
                        valid = true;
                    } else {
                        valid = false;
                    }
                } else {
                    if(!val) {
                        valid = true;
                    }
                }
    
                if(valid) {
                    cb();
                } else {
                    range && range.forEach((v, k) => {
                        cError = cError.replace(`{${k + 1}}`, v);
                    });
                    cError = cError.replace('{0}', label);
                    cb(new Error(cError));
                }
            };
    
            result.validator = validator;
        } else {
            result.message = trigger === 'change' ? '请选择' : '请输入';
        }
    
        return result;
    };
    
    
    export const R = {
        inputNotEmpty(param) {
            return getRule({
                rule: 'notEmpty',
                ...param
            });
        },
    
        chooseNotEmpty(param) {
            return getRule({
                trigger: 'change',
                ...param
            });
        },
    
        // todo: trigger has problem
        arrayNotEmpty(param) {
            return getRule({
                trigger: 'change',
                type: 'array',
                ...param
            });
        },
    
        intNumber(param) {
            return getRule({
                rule: 'number',
                ...param
            });
        }
    };
    
    1. 表单项的展示隐藏控制,通过 hidden 属性控制,分角色,管理员和供应商。
    // 获取字段列表
    getConfigList() {
        return this.fieldList.filter(v => !v.hidden);
    },
     
     
        {
            label: '套餐ID:',
            value: 'packageId',
            type: 'input',
            hidden: !isAdmin
        },
    
    
    1. $attr 支持原有属性的传递:可以在 qform 组件传递任意非 style、class 的原生 el-form 属性。比如 inline、lable-width。
    <q-form
        :ref-obj.sync="form.ref"
        :data="form.data"
        :field-list="form.fields"
        @search="queryList" // search 事件
        inline   // el-form 属性
    ></q-form>
    
    1. 事件传递:内置 submit、search、reset 事件,默认 handle-event。
    // QForm.vue
    <!-- 提交、重置 -->
    <el-button
        v-if="item.type === 'button'"
        :type="item.styleType || 'primary'"
        @click="handleEvent(item.event)"
    >
        {{ item.text }}
    </el-button>
     
    // 绑定的相关事件
    handleEvent(event, data) {
        switch (event) {
            case "submit":
            case "search":
            case "reset":
                this.$emit(event, data);
                this.$emit("handle-event", event, data);
                break;
            default:
                this.$emit("handle-event", event, data);
        }
    },
     
     
    // config.js
    export const taocanFields = [
        {
            text: '提交',
            type: 'button',
            event: 'submit'
        },
        {
            text: '重置',
            type: 'button',
            event: 'reset',
            styleType: 'defalut'
        }
    ]
     
     
     
    // 使用
    <q-form
        :ref-obj.sync="formInfo.ref"
        :data="formInfo.data"
        :field-list="formInfo.fieldList"
        :label-width="formInfo.labelWidth"
        @handle-event="onFormInfoEvent"
        className="form-wrap"
    />
     
     
    // 表单提交
    onFormInfoEvent(event) {
        switch (event) {
            case "submit":
                this.onSubmit();
                break;
            case "reset":
                this.onReset();
                break;
        }
    },
    

    完整代码:https://github.com/obligat/qform-demo

    https://juejin.im/post/6844903841142407175

    相关文章

      网友评论

          本文标题:封装 el-form

          本文链接:https://www.haomeiwen.com/subject/ckyirhtx.html