vue 封装动态生成form表单

动态生成 form 表单组件

<template>
    <div class="form">
        <el-form
            ref="formDom"
            :model="formData"
            :inline="inline"
            :label-width="labelWidth"
            :label-position="labelPosition"
        >
            <el-form-item
                v-for="item in formConfig"
                :key="item.model"
                :label="item.label"
                :label-width="item.labelWidth||'100'"
            >
                <el-input
                    v-if="item.type === 'input'"
                    v-model="formData[item.model]"
                    :type="item.inputType ? item.inputType : 'text'"
                    :placeholder="`请输入${item.label}`"
                    clearable
                />

                <el-date-picker
                    v-if="item.type === 'daterange'"
                    v-model="formData[item.model]"
                    type="daterange"
                    format="yyyy-MM-dd"
                    :style="`
                        width: ${item.width ? item.width : 200}px
                    `"
                    :placeholder="`请选择${item.label}`"
                    @on-change="setDateRange(formData[item.model], item.model)"
                />

                <el-select
                    v-if="item.type === 'select'"
                    v-model="formData[item.model]"
                    clearable
                    :placeholder="`请选择${item.label}`"
                    :multiple="item.multiple"
                    :filterable="item.filterable"
                    :max-tag-count="item.max_tag_count"
                    style="width:100%;"
                >
                    <el-option
                        v-for="data in item.list"
                        :key="getSelectKeys(data, 'key')"
                        :label="getSelectKeys(data, 'value')"
                        :value="getSelectKeys(data, 'key')"
                    >
                        {{ getSelectKeys(data, "value") }}
                    </el-option>
                </el-select>

                <slot name="item" />

                <el-button
                    v-if="item.type === 'confirm'"
                    type="primary"
                    :loading="item.isSearching"
                    @click="submit"
                >
                    查询
                </el-button>

                <el-button
                    v-if="item.type === 'reset'"
                    type="primary"
                    @click="reset"
                >
                    重置
                </el-button>

                <slot name="button" />
            </el-form-item>

            <slot name="form" />
        </el-form>
    </div>
</template>

<script>
export default {
    name: 'CommonForm',
    props: {
        // 表单项是否行内显示
        inline: {
            type: Boolean,
            default: true,
        },
        // 表单项配置
        formConfig: {
            type: Array,
            default: () => []
        },
        // 表单项数据
        formDataInit: {
            type: Object,
            default: () => {}
        },
        // 表单标签宽度
        labelWidth: {
            type: [Number,String],
            default: '100',
        },
        // 表单标签位置,默认左侧
        labelPosition: {
            type: String,
            default: 'left',
        },
    },
    data() {
        return {
            formData: this.formDataInit,
            selectKeys: []
        };
    },
    mounted() {
        // 初始化设置formdata项的开始时间和结束时间
        this.formConfig
            .filter(item => item.type === 'daterange')
            .map(item => {
                this.setDateRange(this.formData[item.model], item.model);
            });
    },
    methods: {
        getSelectKeys(obj, type) {
            const key = Object.keys(obj);
            return type === 'key' ? obj[key[0]] : obj[key[1]];
        },
        // 选取日期后赋给 form 对应属性名
        setDateRange(date, model) {
            this.formData[`${model}_start`] = date[0];
            this.formData[`${model}_stop`] = date[1];
        },
        submit() {
            this.$emit('submit');
        },
        reset() {
            this.$refs.formDom.resetFields();
        }
    },
};
</script>

<style lang="less" scoped>
.form {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;

    .ivu-form-item {
        min-width: 19%;
        margin-bottom: 4px;

        /deep/ .ivu-input-with-suffix {
            padding: 4px;
        }
    }

    /deep/ .ivu-form {
        color: #333;
        width: 100%;
    }
}

@media screen and (max-width: 1300px){
    .ivu-form-item {
        width: 23%;
    };
}
</style>

调用

<!-- 引用 CommonForm -->
<template>
    <div v-cloak>
        <CommonForm
            :formDataInit="formDataInit"
            :form-config="formConfig"
            :label-width="70"
            @submit="getList"
        />
    </div>
</template>

<script>
...
   data() {
       return {
       	    isSearching: false, // // 是否查询中
           formConfig: [ // 表单配置
               { model: 'id', label: 'id', type: 'input'},
{ model: 'ids', label: '项目id', type: 'input'},
               {
                   model: 'status', //  搜索项参数名,和 form 中的参数名一致
                   label: '状态',  // 搜索项标签,即左侧文案
                   type: 'select', // 搜索项类型
                   multiple: true, // 是否支持多选
                   max_tag_count: 1, // 多选时最多显示多少个 tag
                   list: [{
                    value: '选项1',
                    label: '黄金糕'
                    }, {
                    value: '选项2',
                    label: '双皮奶'
                    }, {
                    value: '选项3',
                    label: '蚵仔煎'
                    }, {
                    value: '选项4',
                    label: '龙须面'
                    }, {
                    value: '选项5',
                    label: '北京烤鸭'
                }], // select选择项列表
               },
            {
                model: 'time', //  搜索项参数名,和 form 中的参数名一致
                label: '开始时间',  // 搜索项标签,即左侧文案
                type: 'daterange', // 搜索项类型
            },
            {
                model: 'confirm', // 确认按钮
                text: '查询', // 按钮文案
                type: 'confirm',
                label: '',
                labelWidth: 0,
                isSearching: this.isSearching
               },
           ],
           formDataInit: { // 检索参数
               id: '',
               page_number: 1,
               page_size: 10,
               time: [],
           },
       };
   },
};
</script>

posted @ 2022-06-22 16:39  seekHelp  阅读(1375)  评论(0编辑  收藏  举报