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.效果
自带了表单验证