vue3 + antd 封装动态表单组件(一)
vue
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
项目地址:https://gitcode.com/gh_mirrors/vu/vue
免费下载资源
·
前置条件
vue
版本 v3.3.11
ant-design-vue
版本 v4.1.1
内容梗概
这篇文章的主要内容提供创建动态表单组件的基础模板,相关复杂功能可根据实际的业务场景自行实现。
先看效果图
代码区域
创建动态组件配置文件config.js
import { Input, Textarea, InputNumber, Select, RadioGroup, CheckboxGroup, DatePicker } from 'ant-design-vue';
// 表单域组件类型
export const componentsMap = {
Text: Input,
Textarea,
Number: InputNumber,
Select,
Radio: RadioGroup,
Checkbox: CheckboxGroup,
DatePicker,
}
创建dynamic-form.vue
组件
<template>
<div>
<a-form ref="formRef" :model="formModel" v-bind="$attrs">
<a-form-item
:name="item.field"
:label="item.label"
v-for="item in formSchema"
:key="item.field"
v-bind="item.formItemProps"
>
<component
:is="componentsMap[item.component]"
v-bind="item.componentProps"
v-model:value="formModel[item.field]"
/>
</a-form-item>
</a-form>
</div>
</template>
<script setup>
import { ref, watch, onMounted } from "vue";
import { componentsMap } from "./config.js";
const props = defineProps({
// 表单项配置
schema: {
type: Array,
default: () => [],
},
// 表单model配置,一般用于默认值、回显数据
model: {
type: Object,
default: () => ({}),
},
});
const formRef = ref(null);
const formSchema = ref([]);
const formModel = ref({});
// 表单初始化
const initForm = () => {
formSchema.value = props.schema.map((x) => {
return {
...x,
};
});
// model初始数据
formModel.value = props.schema.reduce((pre, cur) => {
if (!pre[cur.field]) {
// 表单初始数据(默认值)
pre[cur.field] = cur.value;
return pre;
}
}, {});
};
onMounted(() => {
initForm();
// 构建表单项后才回显model值,model会覆盖schema配置的value值
watch(
() => props.model,
(newVal) => {
formModel.value = { ...formModel.value, ...newVal };
},
{
immediate: true,
deep: true,
}
);
});
// 表单验证
const validateFields = () => {
return new Promise((resolve, reject) => {
formRef.value
.validateFields()
.then((formData) => {
resolve(formData);
})
.catch((err) => reject(err));
});
};
// 表单重置
const resetFields = (isInit = true) => {
// 是否清空默认值
if (isInit) {
formModel.value = {};
}
formRef.value.resetFields();
};
// 暴露方法
defineExpose({
validateFields,
resetFields,
});
</script>
使用dynamic-form.vue
组件
<template>
<div style="padding: 200px">
<DynamicForm ref="formRef" :schema="schema" :model="model" :labelCol="{ span: 4 }" :wrapperCol="{ span: 20 }"/>
<div style="display: flex; justify-content: center">
<a-button @click="handleReset(true)">重置(全部清空)</a-button>
<a-button style="margin-left: 50px" @click="handleReset(false)"
>重置</a-button
>
<a-button type="primary" style="margin-left: 50px" @click="handleSubmit"
>提交</a-button
>
</div>
</div>
</template>
<script setup>
import DynamicForm from "@/components/form/dynamic-form.vue";
import { ref } from "vue";
import dayjs from "dayjs";
const formRef = ref(null);
const schema = ref([
{
label: "姓名",
field: "name",
component: "Text",
componentProps: {
allowClear: true,
showCount: true,
maxlength: 20,
style: {
width: "500px",
},
},
formItemProps: {
rules: [
{
required: true,
message: "请输入姓名",
trigger: "blur",
},
],
},
},
{
label: "性别",
field: "sex",
component: "Radio",
componentProps: {
options: [
{ value: 1, label: "男" },
{ value: 2, label: "女" },
{ value: 3, label: "保密" },
],
},
formItemProps: {
rules: [
{
required: true,
message: "请选择性别",
trigger: "blur",
},
],
},
value: 1,
},
{
label: "生日",
field: "birthday",
component: "DatePicker",
formItemProps: {
rules: [
{
required: true,
message: "生日日期不能为空",
trigger: "blur",
},
],
},
},
{
label: "兴趣",
field: "hobby",
component: "Checkbox",
componentProps: {
options: [
{ value: 1, label: "足球" },
{ value: 2, label: "篮球" },
{ value: 3, label: "排球" },
],
},
},
{
label: "国家",
field: "country",
component: "Select",
componentProps: {
allowClear: true,
options: [
{ value: 1, label: "中国" },
{ value: 2, label: "美国" },
{ value: 3, label: "俄罗斯" },
],
},
},
{
label: "简介",
field: "desc",
component: "Textarea",
componentProps: {
allowClear: true,
autoSize: {
minRows: 4,
maxRows: 4,
},
maxlength: 200,
showCount: true,
},
},
]);
const model = ref({ name: "百里守约" });
// 提交
const handleSubmit = async () => {
const formData = await formRef.value.validateFields();
if (formData.birthday) {
formData.birthday = dayjs(formData.birthday).format("YYYY-MM-DD");
}
console.log("提交信息:", formData);
};
// 重置
const handleReset = (isInit) => {
formRef.value.resetFields(isInit);
};
</script>
GitHub 加速计划 / vu / vue
207.54 K
33.66 K
下载
vuejs/vue: 是一个用于构建用户界面的 JavaScript 框架,具有简洁的语法和丰富的组件库,可以用于开发单页面应用程序和多页面应用程序。
最近提交(Master分支:2 个月前 )
73486cb5
* chore: fix link broken
Signed-off-by: snoppy <michaleli@foxmail.com>
* Update packages/template-compiler/README.md [skip ci]
---------
Signed-off-by: snoppy <michaleli@foxmail.com>
Co-authored-by: Eduardo San Martin Morote <posva@users.noreply.github.com> 4 个月前
e428d891
Updated Browser Compatibility reference. The previous currently returns HTTP 404. 5 个月前
更多推荐
已为社区贡献4条内容
所有评论(0)