动态表单
动态表单集成的功能
自定义输入组件,可参考
@erp/biz里的ErpInputinput(text, number, integer, switch, radio, checkbox, update, select, cascader, tree)自定义布局功能通过简单的类栅格配置能实现通用的布局
自定义校验功能通过简单的配置,就能支持通用强大的校验功能。
动态表单组件集成形式
动态表单弹窗形式
动态表单通用配置实例
vue
<template>
<div class="form-demo1">
<DynamicForm :model-value="model" :config="formConfig">
<!-- 支持slots -->
<template #image="{ field, model, modelValue }">
{{ model }}
{{ field }}
{{ modelValue }}
</template>
</DynamicForm>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import { cloneDeep } from 'lodash-es';
import { DynamicForm } from '@erp/biz';
import { config } from './form-config';
import type { PageExpose } from '@erp/biz';
const formConfig = cloneDeep(config);
/**
* 关闭左侧导航
*/
formConfig.showSide = false;
// formConfig.fields[0] = reactive(formConfig.fields[0]);
const model = ref({
key13: '1',
});
setTimeout(() => {
// formConfig.fields[1].type = 'custom';
// formConfig.fields[1].component = 'image';
// /**
// * field 自带响应式
// */
// formConfig.fields[0].options = [
// {
// value: '1',
// label: '订单类型一',
// },
// {
// value: '2',
// label: '订单类型二',
// },
// {
// value: '3',
// label: '订单类型三',
// },
// {
// value: '4',
// label: '订单类型四',
// },
// ];
}, 3000);
defineExpose<PageExpose>({
getModel() {
return model.value;
},
});
</script>
<style lang="scss" scoped>
.form-demo1 {
padding: 0;
border: 1px solid var(--color-border-1);
border-radius: var(--border-radius-small);
height: 560px;
}
</style>ts
import GoodsGrid from './goods-grid.vue';
import type { DynamicFormI } from '@erp/biz';
export const config: DynamicFormI = {
title: '商品订单',
showSide: true,
// 这个按钮配置需要考虑 modal / drawer,此配置与该组件的buttons配置重复
// buttons: [
// {
// label: '提交',
// code: 'submit',
// type: 'primary',
// validator: 'field',
// },
// {
// label: '取消',
// code: 'cancel',
// type: 'info',
// },
// ],
cols: 3,
colGap: 12,
components: {
GoodsGrid,
},
// fields: [
// {
// key: 'address',
// label: '地市',
// type: 'cascader',
// componentProps: {
// pathMode: true,
// },
// options: [
// {
// value: 'beijing',
// label: 'Beijing',
// children: [
// {
// value: 'chaoyang',
// label: 'ChaoYang',
// children: [
// {
// value: 'datunli',
// label: 'Datunli',
// },
// ],
// },
// {
// value: 'haidian',
// label: 'Haidian',
// },
// {
// value: 'dongcheng',
// label: 'Dongcheng',
// },
// {
// value: 'xicheng',
// label: 'Xicheng',
// children: [
// {
// value: 'jinrongjie',
// label: 'Jinrongjie',
// },
// {
// value: 'tianqiao',
// label: 'Tianqiao',
// },
// ],
// },
// ],
// },
// {
// value: 'shanghai',
// label: 'Shanghai',
// children: [
// {
// value: 'huangpu',
// label: 'Huangpu',
// },
// ],
// },
// ],
// },
// {
// key: 'orderType',
// label: '订单类型',
// type: 'select',
// required: true,
// options: [
// {
// value: '1',
// label: '订单类型一',
// },
// ],
// },
// {
// key: 'key2.key',
// label: '店铺',
// required: true,
// type: 'select',
// options: [
// {
// value: 1,
// label: '店铺一',
// },
// ],
// },
// {
// key: 'key3',
// label: '下单时间',
// type: 'date',
// },
// {
// key: 'key4',
// label: '运费',
// type: 'number',
// },
// {
// key: 'key5',
// label: '买家账号',
// type: 'text',
// required: true,
// },
// {
// key: 'key6',
// label: '买家名称',
// type: 'text',
// required: true,
// },
// {
// key: 'key7',
// label: '业务员',
// type: 'select',
// required: true,
// options: [],
// },
// {
// key: 'key8',
// label: '商机编号',
// type: 'text',
// },
// {
// key: 'key9',
// label: '经销商',
// type: 'text',
// },
// {
// key: 'key10',
// label: '派单人员',
// type: 'select',
// options: [],
// },
// {
// key: 'key11',
// label: '归属手机',
// type: 'text',
// rules: {
// type: 'string',
// validator(value, callback) {
// // 校验手机
// callback();
// },
// },
// },
// ],
groups: [
{
label: '基础信息',
fields: [
{
key: 'orderType',
label: '订单类型',
type: 'select',
required: true,
options: [
{
value: '1',
label: '订单类型一',
},
],
},
{
key: 'key2.key',
label: '店铺',
required: true,
type: 'select-shop',
},
{
key: 'key3',
label: '下单时间',
type: 'date',
},
{
key: 'key4',
label: '运费',
type: 'number',
},
{
key: 'key5',
label: '买家账号',
type: 'text',
required: true,
},
{
key: 'key6',
label: '买家名称',
type: 'text',
required: true,
},
{
key: 'key7',
label: '业务员',
type: 'select',
required: true,
options: [
{
label: '张三',
value: '1',
},
],
},
{
key: 'key8',
label: '商机编号',
type: 'text',
},
{
key: 'key9',
label: '经销商',
type: 'text',
},
{
key: 'key10',
label: '派单人员',
type: 'select',
options: [],
},
{
key: 'key113',
label: '归属手机',
type: 'text',
rules: {
type: 'string',
validator(value, callback) {
// 校验手机
callback();
},
},
},
],
},
{
label: '收货信息',
cols: 3,
tip: '收货信息',
fields: [
{
key: 'address',
label: '收货人',
type: 'text',
placeholder: '请输入收货人姓名',
required: true,
},
{
key: 'phone',
label: '联系人电话',
type: 'text',
required: true,
tooltip: '请输入联系电话',
},
{
key: 'key13',
label: '智能解析',
type: 'textarea',
},
{
key: 'key115',
label: '收货地址',
type: 'cascader',
required: true,
options: [
{
value: 'beijing',
label: 'Beijing',
children: [
{
value: 'chaoyang',
label: 'ChaoYang',
children: [
{
value: 'datunli',
label: 'Datunli',
},
],
},
{
value: 'haidian',
label: 'Haidian',
},
{
value: 'dongcheng',
label: 'Dongcheng',
},
{
value: 'xicheng',
label: 'Xicheng',
children: [
{
value: 'jinrongjie',
label: 'Jinrongjie',
},
{
value: 'tianqiao',
label: 'Tianqiao',
},
],
},
],
},
{
value: 'shanghai',
label: 'Shanghai',
children: [
{
value: 'huangpu',
label: 'Huangpu',
},
],
},
],
},
{
key: 'key12',
label: '详细地址',
type: 'text',
required: true,
placeholder: '请输入具体街道/楼栋/房号等信息',
},
{
key: 'key13',
label: '使用代发地址',
tooltip: '使用代发地址',
type: 'switch',
row: {
wrap: false,
align: 'end',
},
options: [
{
value: 1,
label: '是',
},
{
value: 2,
label: '否',
},
],
},
],
},
{
label: '商品信息',
buttons: [
{
code: 'add-shop',
label: '添加商品',
type: 'text',
status: 'normal',
size: 'small',
},
],
fields: [
{
key: 'goods',
span: 2,
multiple: true,
type: 'custom',
component: 'GoodsGrid',
hideLabel: true,
},
],
},
{
label: '卖家备注',
fields: [
{
key: 'key111',
label: '旗帜颜色',
tooltip: '旗帜颜色',
type: 'text',
span: 2,
},
{
key: 'key112',
label: '定制内容',
type: 'textarea',
placeholder: '请输入需要定制的内容,最多不超过300字',
},
{
key: 'key113',
label: '备注',
type: 'textarea',
placeholder: '系统会根据您选择的商品+定制内容,自动生成备注',
},
],
},
{
label: '加工信息',
fields: [],
},
{
label: '附件信息',
fields: [
{
key: 'key123',
type: 'upload',
span: 2,
},
],
},
],
};动态表单 API
<dynamic-form> Props
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| model-value (v-model) | 绑定值 | Record<string, any> | function() { return {}; } |
| config (必填) | DynamicFormI 动态表单配置 | DynamicFormI | - |
<dynamic-form> Events
| 事件名 | 描述 | 参数 |
|---|---|---|
| update:model-value | 表单数据模型 | - |
| ok | 表单ok事件,可配合 createPage createModal createDrawer使用 | params: mixed |
| close | 表单close事件,可配合 createPage createModal createDrawer使用 | params: mixed |
| loading | 表单 loading 事件,可配合 createModal createDrawer使用 | params: mixed |
| click | 表单里配置的按钮事件 | button: mixed |
<dynamic-form> Slots
| 插槽名 | 描述 | 参数 |
|---|---|---|
| form-footer | 表单底部slot | - |
| form-header | 表单头部slot | - |
| side-footer | 侧边栏footer | - |
FormButtonType
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| code | 按钮唯一标识 | string | - |
| visible | 是否可见 | Ref<boolean> | ComputedRef<boolean> | boolean | (() => boolean) | - |
| validator | 校验配置 true 为 自动校验 field 一个一个的字段校验 | boolean | 'field' | ((model: Record<string, any>, form: FormInstance) => Promise<Record<string, ValidatedError> | undefined>) | - |
DynamicFormI
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| $id | 表单ID | string | - |
| title | 表单标题 | string | - |
| fields | 表单字段 | DynamicFormFieldI[] | - |
| groups | 表单组 | DynamicFormGroupI[] | - |
| showSide | 是否显示左侧导航 默认显示 | boolean | false |
| buttons | 显示button | FormButtonType[] | - |
| layout | 表单字段布局 | 'horizontal' | 'vertical' | 'inline' | - |
| labelAlign | label方向 | 'left' | 'right' | - |
| cols | 每一行展示的列数 | number | - |
| colGap | 列与列之间的间距 | number | - |
| components | 动态组件 只能第一次注册 | Record<string, Component> | - |
DynamicFormGroupI
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| $id | 由框架自己生成 | string | - |
| label | 表单域标签 | string | - |
| fields | 表单字段 | DynamicFormFieldI[] | - |
| cols | 每一行展示的列数 | number | - |
| colGap | 列与列之间的间距 | number | - |
| rowGap | 行与行之间的间距 | number | - |
| span | 跨越的格数 对表单子域有效 | number | - |
| offset | 左侧的间隔格数 对表单子域有效 | number | - |
| buttons | 显示button | FormButtonType[] | - |
| tip | 提示信息 | string | - |
| children | 子表单 | DynamicFormGroupI[] | - |
| visible | 是否显示 | Ref<boolean> | ComputedRef<boolean> | boolean | (() => boolean) | - |
DynamicFormFieldI
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| $id | id 自动生成 | string | - |
| key | 数据模式key,符合propertyKey | string | - |
| type | 组件类型 | InputType | 'custom' | - |
| component | 组件 | Component | string | - |
| componentProps | 组件额外配置 除了 DynamicFormFieldI 自带的属性外,如果组件特有的属性外都在此配置 | T | - |
| label | 标签的文本 | string | - |
| multiple | 是否多值 | boolean | false |
| disabled | 是否禁用 | boolean | Ref<boolean> | ComputedRef<boolean> | - |
| placeholder | 占位 | string | - |
| options | 组件数据配置 | OptionData[] | (() => Promise<OptionData[]>) | - |
| tooltip | 提示内容 | string | - |
| showColon | 是否显示冒号 | boolean | false |
| noStyle | 是否去除样式 | boolean | false |
| help | 帮助文案 | string | - |
| required | 是否必须填写 | boolean | false |
| rules | 表单项校验规则 | FieldRule | FieldRule[] | - |
| validateStatus | 校验状态 | ValidateStatus | - |
| validateTrigger | 触发校验的事件 | ValidateTrigger | - |
| hideLabel | 是否隐藏标签 | boolean | false |
| hideAsterisk | 是否隐藏星号 | boolean | false |
| feedback | 是否显示表单控件的反馈图标 | boolean | false |
| row | 表单项布局选项 | RowProps | - |
| labelColProps | 标签元素布局选项。参数同 <col> 组件一致 | any | - |
| wrapperColProps | 表单控件布局选项。参数同 <col> 组件一致 | any | - |
| span | 跨越的格数 | number | - |
| offset | 左侧的间隔格数 | number | - |
| class | class | string | - |
| show | 是否显示 隐藏的字段不做校验 | boolean | (() => boolean) | - |
| slots | FormItem slots配置 | { label?: RenderFunction; help?: RenderFunction; extra?: RenderFunction; prefix?: RenderFunction; suffix?: RenderFunction; } | - |
DynamicFieldComponentProps
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| field | 子组件的表单域配置 | DynamicFormFieldI<T> | - |
| model | 表单数据模型 | Record<string, any> | - |
| modelValue (v-model) | 对应表单的值 | any | - |
DynamicFieldComponentExpose
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| validate | 校验 true 通过 false 未通过 | () => boolean | string | Promise<boolean | string> | - |
<buttons> Props
按钮组
| 参数名 | 描述 | 类型 | 默认值 |
|---|---|---|---|
| buttons | 按钮配置 | FormButtonType[] | [] |
| loading | 是否加载中 | boolean | false |
<buttons> Events
| 事件名 | 描述 | 参数 |
|---|---|---|
| click | 点击事件 | evt: mixedbutton: mixed |