优化更新

This commit is contained in:
2026-09-14 10:33:29 +08:00
parent e8b5d55603
commit 11c46addfa
61 changed files with 1025 additions and 896 deletions
@@ -1,7 +1,7 @@
# BasicForm 表单
:::tip 说明
`BasicForm` 位于 `src/components/Form/src/BasicForm.vue`,基于 ElementPlus 的 `el-form` 二次封装,通过 schemas 配置化定义表单字段,支持查询表单和业务表单两种模式。
`BasicForm` 位于 `src/components/Form/src/BasicForm.vue`,基于 NaiveUI 的 `n-form` 二次封装,通过 schemas 配置化定义表单字段,支持查询表单和业务表单两种模式。
:::
## 组件架构
@@ -24,9 +24,9 @@ src/components/Form/
列表页的搜索区域使用 `useForm` 注册表单:
```vue
<el-card :bordered="false" class="pt-3 mb-3 proCard">
<n-card :bordered="false" class="pt-3 mb-3 proCard">
<BasicForm @register="register" @submit="handleSubmit" @reset="handleReset" />
</el-card>
</n-card>
```
### querySchemas 定义
@@ -39,7 +39,7 @@ import { FormSchema } from '@/components/Form/index';
export const schemas: FormSchema[] = [
{
field: 'name',
component: 'Input',
component: 'NInput',
label: '岗位名称',
componentProps: {
placeholder: '请输入岗位名称',
@@ -47,7 +47,7 @@ export const schemas: FormSchema[] = [
},
{
field: 'status',
component: 'Select',
component: 'NSelect',
label: '状态',
componentProps: {
placeholder: '请选择状态',
@@ -66,14 +66,13 @@ export const schemas: FormSchema[] = [
```typescript
import { schemas } from './querySchemas';
import { useForm } from '@/components/Form/index';
import { ColProps } from 'element-plus';
const formParams = reactive({ name: '', status: '' });
const [register, {}] = useForm({
labelWidth: 80,
layout: 'horizontal',
colProps: { span: 6 } as ColProps,
colProps: { span: 6 },
submitOnReset: true,
schemas,
});
@@ -93,73 +92,71 @@ function handleReset() {
## 业务表单(编辑弹窗)
编辑弹窗中直接使用 `el-form` + `el-form-item` 构建表单:
编辑弹窗中直接使用 `n-form` + `n-form-item` 构建表单:
```vue
<!-- src/views/system/position/edit.vue -->
<template>
<el-dialog v-model="props.visible" :title="props.positionId ? '编辑' : '新增'" width="500">
<el-form class="ls-form" ref="formRef" :model="formData" label-width="80px">
<el-form-item
<n-modal v-model:show="props.visible" :title="props.positionId ? '编辑' : '新增'" :style="{ width: '500px' }">
<n-form class="ls-form" ref="formRef" :model="formData" label-width="80px">
<n-form-item
label="岗位名称"
prop="name"
:rules="{ required: true, message: '请输入岗位名称', trigger: 'blur' }"
path="name"
:rule="{ required: true, message: '请输入岗位名称', trigger: 'blur' }"
>
<el-input v-model="formData.name" placeholder="请输入岗位名称" clearable />
</el-form-item>
<el-form-item label="岗位状态" prop="status">
<el-radio-group v-model="formData.status">
<el-radio :value="1">正常</el-radio>
<el-radio :value="2">停用</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input-number v-model="formData.sort" />
</el-form-item>
</el-form>
</el-dialog>
<n-input v-model:value="formData.name" placeholder="请输入岗位名称" clearable />
</n-form-item>
<n-form-item label="岗位状态" path="status">
<n-radio-group v-model:value="formData.status">
<n-radio :value="1">正常</n-radio>
<n-radio :value="2">停用</n-radio>
</n-radio-group>
</n-form-item>
<n-form-item label="排序" path="sort">
<n-input-number v-model:value="formData.sort" />
</n-form-item>
</n-form>
</n-modal>
</template>
```
## BasicForm 内部渲染机制
`BasicForm.vue` 根据 `schema.component` 动态渲染对应的 ElementPlus 组件:
`BasicForm.vue` 根据 `schema.component` 动态渲染对应的 NaiveUI 组件:
```vue
<!-- src/components/Form/src/BasicForm.vue 核心逻辑 -->
<template v-for="schema in getSchema" :key="schema.field">
<!-- Checkbox -->
<template v-if="schema.component === 'Checkbox'">
<el-checkbox-group v-model="formModel[schema.field]">
<el-checkbox v-for="item in schema.componentProps?.options" :value="item.value">
<template v-if="schema.component === 'NCheckbox'">
<n-checkbox-group v-model:value="formModel[schema.field]">
<n-checkbox v-for="item in schema.componentProps?.options" :value="item.value">
{{ item.label }}
</el-checkbox>
</el-checkbox-group>
</n-checkbox>
</n-checkbox-group>
</template>
<!-- RadioGroup -->
<template v-else-if="schema.component === 'RadioGroup'">
<el-radio-group v-model="formModel[schema.field]">
<el-radio v-for="item in schema.componentProps?.options" :value="item.value">
<template v-else-if="schema.component === 'NRadioGroup'">
<n-radio-group v-model:value="formModel[schema.field]">
<n-radio v-for="item in schema.componentProps?.options" :value="item.value">
{{ item.label }}
</el-radio>
</el-radio-group>
</n-radio>
</n-radio-group>
</template>
<!-- Select -->
<template v-else-if="schema.component === 'Select'">
<el-select v-model="formModel[schema.field]">
<el-option v-for="item in schema.componentProps?.options" :value="item.value" :label="item.label" />
</el-select>
<template v-else-if="schema.component === 'NSelect'">
<n-select v-model:value="formModel[schema.field]" :options="schema.componentProps?.options" />
</template>
<!-- Daterange -->
<template v-else-if="schema.component === 'Daterange'">
<el-date-picker v-model="formModel[schema.field]" type="daterange" value-format="YYYY-MM-DD" />
<template v-else-if="schema.component === 'NDatePicker'">
<n-date-picker v-model:value="formModel[schema.field]" type="daterange" value-format="yyyy-MM-dd" />
</template>
<!-- 其他组件:动态渲染 el-{component} -->
<component v-else :is="`el-${schema.component}`" v-model="formModel[schema.field]" />
<!-- 其他组件:动态渲染 -->
<component v-else :is="schema.component" v-model:value="formModel[schema.field]" />
</template>
```
@@ -169,7 +166,7 @@ function handleReset() {
interface FormSchema {
field: string; // 字段名
label: string; // 标签文本
component: string; // 组件类型:Input / Select / RadioGroup / Checkbox / DatePicker 等
component: string; // 组件类型:NInput / NSelect / NRadioGroup / NCheckbox / NDatePicker 等
componentProps?: any; // 组件属性(placeholder、options、clearable 等)
required?: boolean; // 是否必填
rules?: any[]; // 自定义校验规则
@@ -202,7 +199,7 @@ Schema 中的 `required: true` 会自动生成必填校验规则,也可以通
{
field: 'name',
label: '岗位名称',
component: 'Input',
component: 'NInput',
rules: [
{ required: true, message: '请输入岗位名称', trigger: 'blur' },
{ min: 1, max: 150, message: '长度在 1 到 150 个字符', trigger: 'blur' },
@@ -237,4 +234,4 @@ onMounted(() => {
## 总结
BasicForm 通过 schemas 配置化定义表单字段,内部根据 `component` 动态渲染对应的 ElementPlus 组件。查询表单使用 `useForm` 注册并绑定 `@submit`/`@reset` 事件,业务表单直接使用 `el-form` + `reactive` 管理数据。支持多种组件类型、表单校验、数据绑定、条件隐藏等能力。
BasicForm 通过 schemas 配置化定义表单字段,内部根据 `component` 动态渲染对应的 NaiveUI 组件。查询表单使用 `useForm` 注册并绑定 `@submit`/`@reset` 事件,业务表单直接使用 `n-form` + `reactive` 管理数据。支持多种组件类型、表单校验、数据绑定、条件隐藏等能力。