Appearance
表单组件的封装
TIP
这个表单组件只是一个封装,具体实现请自行实现。
Form.vue
组件
vue
<template>
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
class="generic-form"
>
<div v-for="item in formItems" :key="item.field">
<el-form-item :label="item.label" :prop="item.field">
<template v-if="item.type === 'input'">
<el-input
v-model="formData[item.field]"
:placeholder="item.placeholder"
:type="item.inputType"
></el-input>
</template>
<template v-else-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-option>
</el-select>
</template>
<template v-else-if="item.type === 'date'">
<el-date-picker
v-model="formData[item.field]"
type="date"
:placeholder="item.placeholder"
></el-date-picker>
</template>
<template v-else-if="item.type === 'datetime'">
<el-date-picker
v-model="formData[item.field]"
type="datetime"
:placeholder="item.placeholder"
></el-date-picker>
</template>
<template v-else-if="item.type === 'radio'">
<el-radio-group v-model="formData[item.field]">
<el-radio
v-for="option in item.options"
:key="option.value"
:label="option.value"
>{{ option.label }}</el-radio>
</el-radio-group>
</template>
<template v-else-if="item.type === 'checkbox'">
<el-checkbox-group v-model="formData[item.field]">
<el-checkbox
v-for="option in item.options"
:key="option.value"
:label="option.value"
>{{ option.label }}</el-checkbox>
</el-checkbox-group>
</template>
<template v-else-if="item.type === 'switch'">
<el-switch v-model="formData[item.field]"></el-switch>
</template>
<template v-else-if="item.type === 'password'">
<el-input
v-model="formData[item.field]"
:placeholder="item.placeholder"
type="password"
show-password
></el-input>
</template>
<!-- 可以根据需要添加更多表单控件类型 -->
</el-form-item>
</div>
<el-form-item>
<slot name="submit"></slot>
<slot name="reset"></slot>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: Object,
formItems: Array,
rules: Object,
});
const emit = defineEmits(['update:modelValue', 'submit']);
const formData = ref(props.modelValue);
const formRef = ref(null);
watch(
() => props.modelValue,
(newValue) => {
formData.value = newValue;
},
{ deep: true }
);
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
emit('submit', formData.value);
} else {
console.log('表单验证失败');
}
});
};
const resetForm = () => {
formRef.value.resetFields();
emit('update:modelValue', {});
};
</script>
<style scoped lang="scss">
.generic-form {
width: 500px;
margin: 20px auto;
}
</style>
<template>
<el-form
ref="formRef"
:model="formData"
:rules="rules"
label-width="100px"
class="generic-form"
>
<div v-for="item in formItems" :key="item.field">
<el-form-item :label="item.label" :prop="item.field">
<template v-if="item.type === 'input'">
<el-input
v-model="formData[item.field]"
:placeholder="item.placeholder"
:type="item.inputType"
></el-input>
</template>
<template v-else-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-option>
</el-select>
</template>
<template v-else-if="item.type === 'date'">
<el-date-picker
v-model="formData[item.field]"
type="date"
:placeholder="item.placeholder"
></el-date-picker>
</template>
<template v-else-if="item.type === 'datetime'">
<el-date-picker
v-model="formData[item.field]"
type="datetime"
:placeholder="item.placeholder"
></el-date-picker>
</template>
<template v-else-if="item.type === 'radio'">
<el-radio-group v-model="formData[item.field]">
<el-radio
v-for="option in item.options"
:key="option.value"
:label="option.value"
>{{ option.label }}</el-radio>
</el-radio-group>
</template>
<template v-else-if="item.type === 'checkbox'">
<el-checkbox-group v-model="formData[item.field]">
<el-checkbox
v-for="option in item.options"
:key="option.value"
:label="option.value"
>{{ option.label }}</el-checkbox>
</el-checkbox-group>
</template>
<template v-else-if="item.type === 'switch'">
<el-switch v-model="formData[item.field]"></el-switch>
</template>
<template v-else-if="item.type === 'password'">
<el-input
v-model="formData[item.field]"
:placeholder="item.placeholder"
type="password"
show-password
></el-input>
</template>
<!-- 可以根据需要添加更多表单控件类型 -->
</el-form-item>
</div>
<el-form-item>
<slot name="submit"></slot>
<slot name="reset"></slot>
</el-form-item>
</el-form>
</template>
<script setup>
import { ref, watch } from 'vue';
const props = defineProps({
modelValue: Object,
formItems: Array,
rules: Object,
});
const emit = defineEmits(['update:modelValue', 'submit']);
const formData = ref(props.modelValue);
const formRef = ref(null);
watch(
() => props.modelValue,
(newValue) => {
formData.value = newValue;
},
{ deep: true }
);
const submitForm = () => {
formRef.value.validate((valid) => {
if (valid) {
emit('submit', formData.value);
} else {
console.log('表单验证失败');
}
});
};
const resetForm = () => {
formRef.value.resetFields();
emit('update:modelValue', {});
};
</script>
<style scoped lang="scss">
.generic-form {
width: 500px;
margin: 20px auto;
}
</style>
页面中调用
vue
<template>
<div>
<Form
v-model="userForm"
:form-items="formItems"
:rules="rules"
@submit="handleFormSubmit"
>
<template #submit>
<el-button type="primary" @click="submitForm">提交</el-button>
</template>
<template #reset>
<el-button @click="resetForm">重置</el-button>
</template>
</Form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Form from '../components/Form.vue';
const userForm = ref({
name: '',
age: '',
gender: '',
birthDate: '',
password: '',
isAgree: false,
hobbies: [],
startTime: '',
endTime: '',
});
const formItems = [
{
label: '姓名',
field: 'name',
type: 'input',
placeholder: '请输入姓名',
},
{
label: '年龄',
field: 'age',
type: 'input',
placeholder: '请输入年龄',
},
{
label: '性别',
field: 'gender',
type: 'select',
placeholder: '请选择性别',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
},
{
label: '出生日期',
field: 'birthDate',
type: 'date',
placeholder: '请选择出生日期',
},
{
label: '密码',
field: 'password',
type: 'password',
placeholder: '请输入密码',
},
{
label: '是否同意',
field: 'isAgree',
type: 'switch',
},
{
label: '爱好',
field: 'hobbies',
type: 'checkbox',
options: [
{ label: '读书', value: 'reading' },
{ label: '运动', value: 'sports' },
{ label: '旅行', value: 'travel' },
],
},
{
label: '开始时间',
field: 'startTime',
type: 'datetime',
placeholder: '请选择开始时间',
},
{
label: '结束时间',
field: 'endTime',
type: 'datetime',
placeholder: '请选择结束时间',
},
];
const rules = {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
],
age: [
{ required: true, message: '请输入年龄', trigger: 'blur' },
{ pattern: /^\d+$/, message: '年龄必须为数字', trigger: 'blur' },
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change' },
],
birthDate: [
{ required: true, message: '请选择出生日期', trigger: 'change' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度至少为6位', trigger: 'blur' },
],
startTime: [
{ required: true, message: '请选择开始时间', trigger: 'change' },
],
endTime: [
{ required: true, message: '请选择结束时间', trigger: 'change' },
],
};
const submitForm = (formData) => {
// 表单提交逻辑
console.log('表单提交数据:', formData);
};
const resetForm = () => {
// 表单重置逻辑
};
const handleFormSubmit = (formData) => {
console.log('表单提交数据:', formData);
// 这里可以进行表单提交的后续操作,如发送请求等
};
</script>
<template>
<div>
<Form
v-model="userForm"
:form-items="formItems"
:rules="rules"
@submit="handleFormSubmit"
>
<template #submit>
<el-button type="primary" @click="submitForm">提交</el-button>
</template>
<template #reset>
<el-button @click="resetForm">重置</el-button>
</template>
</Form>
</div>
</template>
<script setup>
import { ref } from 'vue';
import Form from '../components/Form.vue';
const userForm = ref({
name: '',
age: '',
gender: '',
birthDate: '',
password: '',
isAgree: false,
hobbies: [],
startTime: '',
endTime: '',
});
const formItems = [
{
label: '姓名',
field: 'name',
type: 'input',
placeholder: '请输入姓名',
},
{
label: '年龄',
field: 'age',
type: 'input',
placeholder: '请输入年龄',
},
{
label: '性别',
field: 'gender',
type: 'select',
placeholder: '请选择性别',
options: [
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
},
{
label: '出生日期',
field: 'birthDate',
type: 'date',
placeholder: '请选择出生日期',
},
{
label: '密码',
field: 'password',
type: 'password',
placeholder: '请输入密码',
},
{
label: '是否同意',
field: 'isAgree',
type: 'switch',
},
{
label: '爱好',
field: 'hobbies',
type: 'checkbox',
options: [
{ label: '读书', value: 'reading' },
{ label: '运动', value: 'sports' },
{ label: '旅行', value: 'travel' },
],
},
{
label: '开始时间',
field: 'startTime',
type: 'datetime',
placeholder: '请选择开始时间',
},
{
label: '结束时间',
field: 'endTime',
type: 'datetime',
placeholder: '请选择结束时间',
},
];
const rules = {
name: [
{ required: true, message: '请输入姓名', trigger: 'blur' },
],
age: [
{ required: true, message: '请输入年龄', trigger: 'blur' },
{ pattern: /^\d+$/, message: '年龄必须为数字', trigger: 'blur' },
],
gender: [
{ required: true, message: '请选择性别', trigger: 'change' },
],
birthDate: [
{ required: true, message: '请选择出生日期', trigger: 'change' },
],
password: [
{ required: true, message: '请输入密码', trigger: 'blur' },
{ min: 6, message: '密码长度至少为6位', trigger: 'blur' },
],
startTime: [
{ required: true, message: '请选择开始时间', trigger: 'change' },
],
endTime: [
{ required: true, message: '请选择结束时间', trigger: 'change' },
],
};
const submitForm = (formData) => {
// 表单提交逻辑
console.log('表单提交数据:', formData);
};
const resetForm = () => {
// 表单重置逻辑
};
const handleFormSubmit = (formData) => {
console.log('表单提交数据:', formData);
// 这里可以进行表单提交的后续操作,如发送请求等
};
</script>