element-plus的from二次封装

1.在components中创建 

<template>
    <el-form label-width="auto" style="max-width: 100%" :model="formData" ref="formRef" :rules="rules">
        <div class="header">
            <slot name="header"></slot>
        </div>
        <el-divider border-style="double" />
        <template v-for="(item, index) in formItems" :key="index">
            <el-form-item :label="item.label" :prop="item.field">
                <template v-if="item.type === 'input'||item.type === 'password'">
                    <el-input 
                        :placeholder="item.placeholder"
                        :show-password="item.type === 'password'"
                        v-model="formData[item.field]"
                    />
                </template>
                <template v-if="item.type === 'data'">
                    <el-date-picker v-model="formData[item.field]" type="date" :placeholder="item.placeholder" />
                </template>
                <template v-if="item.type === 'datas'">
                    <el-date-picker :type="item.type" v-bind="item.otherOptions" v-model="formData[item.field]"/>
                </template>
                <template v-if="item.type === 'select'">
                    <el-select v-model="formData[item.field]" :placeholder="item.placeholder">
                        <el-option v-for="option in item.options" :key="option.value" :label="option.label"
                            :value="option.value" />
                    </el-select>
                </template>
                <template v-if="item.type === 'state'">
                    <el-switch v-model="formData[item.field]" />
                </template>
                <template v-if="item.type === 'choice'">
                    <el-radio-group v-model="formData[item.field]">
                        <el-radio :border="item.border" v-for="checkbox in item.checkboxs" :key="checkbox.value"
                            :value="checkbox.value">{{ checkbox.label }}</el-radio>
                    </el-radio-group>
                </template>
                <template v-if="item.type === 'choice1'">
                    <el-segmented v-model="formData[item.field]" :options="item.checkboxs" />
                </template>
                <template v-if="item.type === 'choices'">
                    <el-checkbox-group v-model="formData[item.field]">
                        <el-checkbox v-for="checkbox in item.checkboxs" :key="checkbox.value" :value="checkbox.value"
                            name="type">
                            {{ checkbox.label }}
                        </el-checkbox>
                    </el-checkbox-group>
                </template>
                <template v-if="item.type === 'choices1'">
                    <el-checkbox-group v-model="formData[item.field]">
                        <el-checkbox-button v-for="checkbox in item.checkboxs" :key="checkbox.value"
                            :value="checkbox.value" name="type">
                            {{ checkbox.label }}
                        </el-checkbox-button>
                    </el-checkbox-group>
                </template>
                <template v-if="item.type === 'textarea'">
                    <el-input v-model="formData[item.field]" type="textarea" :placeholder="item.placeholder" />
                </template>
            </el-form-item>

        </template>
        <el-form-item>
            <el-button type="primary" @click="reset">重置</el-button>
            <el-button @click="submit">确定</el-button>
        </el-form-item>
    </el-form>
</template>

<script setup>
import { ref, defineProps,defineEmits,reactive } from 'vue'
const formRef = ref(null)
const props = defineProps({
    formItems: {
        type: Array,
    }
})
const formInit = {}

const rules = reactive({})

const formItems = props.formItems ?? {};
formItems.map(item=>{
  if(item.type === 'choices' || item.type === 'choices1'){
    formInit[item.field] = [];
  }else if(item.type === 'choice' || item.type === 'choice1'){
    formInit[item.field] =item.checkboxs[0].value;
  }else if(item.type === 'state'){
    formInit[item.field] =false;
  }else{
    formInit[item.field] = '';
  }

  let isRequired=item.required===undefined?true:false;
  console.log(item.required);
  if(item.type === 'input' || item.type === 'password' || item.type === 'textarea'){
    rules[item.field] = [
      { required: isRequired, message: `请输入${item.label}`, trigger: 'blur' }
    ]
  }else{
    rules[item.field] = [
      { required: isRequired, message: `请选择${item.label}`, trigger: 'change' }
    ]
  }
})
const formData = ref(formInit);
const emit=defineEmits(['reset','submit'])
// 重置
const reset=()=>{
    formRef.value?.resetFields(); 
    emit('reset');
}
// 提交
const submit=async ()=>{
    formRef.value?.validate((valid, fields) => {
        if (valid) {
            emit('submit',formData.value);
        }else {
        console.log('error submit!', fields)
        }
  })
}
</script>
<style>
    .header{
        font-size: 20px;
        color: #606266;
        font-weight: bold;
    }
</style>

2.使用

3.我把表单的ts分出来了

//type:输入框的类型
//placeholder:默认提示
//field:数据返回的键名
const formItems: FormItem[] = [
    {
        field: 'userName',
        label: '用户名',
        type: 'input',
        placeholder: '请输入用户名',
    },
    {
        field: 'password',
        label: '密码',
        type: 'password',
        placeholder: '请输入密码',
    },
    {
        field: 'role',
        label: '角色',
        type: 'select',
        placeholder: '请选择角色',
        options: [
            {
                label: '管理员',
                value: 1
            },
            {
                label: '普通用户',
                value: 2
            },
            {
                label: '游客',
                value: 3
            }
        ]
    },
    {
        field: 'openTime',
        label: '时间',
        type: 'data',
        placeholder: '请选择时间',
    },
    {
        field: 'openTimeRange',
        label: '时间段',
        type: 'datas',
        placeholder: '请选择时间',
        otherOptions: {
            startPlaceholder: '开始时间',
            endPlaceholder: '结束时间',
            type: 'daterange'
        }
    },
    {
        field: 'state',
        label: '状态',
        type: 'state',
    },
    {
        field: 'choice',
        label: '单选',
        type: 'choice',
        border: true,
        checkboxs: [
            {
                label: '选项1',
                value: 1
            },
            {
                label: '选项2',
                value: 2
            }
        ]
    },
    {
        field: 'choice1',
        label: '单选1',
        type: 'choice1',
        checkboxs: [
            {
                label: '选项1',
                value: 1
            },
            {
                label: '选项2',
                value: 2
            }
        ]
    },
    {
        field: 'choices',
        label: '多选',
        type: 'choices',
        checkboxs: [
            {
                label: '选项1',
                value: 1
            },
            {
                label: '选项2',
                value: 2
            },
            {
                label: '选项3',
                value: 3
            },
        ]
    },
    {
        field: 'choices1',
        label: '多选1',
        type: 'choices1',
        checkboxs: [
            {
                label: '选项1',
                value: 1
            },
            {
                label: '选项2',
                value: 2
            },
            {
                label: '选项3',
                value: 3
            },
        ]
    },
    {
        field: 'textarea',
        label: '备注',
        type: 'textarea',
        required : false,
        placeholder: '请输入备注',
    },
];

export default formItems;

4.效果

自带了表单验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值