BasicForm表单
基于Ant Design Vue
封装的form 组件 BasicForm
,用于快速渲染表单的重要组件。为了简化使用,做了深度的hook封装。如果需要扩展,请修改hook /@/hooks/useForm.ts
通过jeecg封装的BasicForm表单控件,可以快速的渲染表单,不需要写太多原生代码。(当然各有利弊,此表单组件封装的很智能,同时可能会带来不灵活的问题,所以特别复杂的表单可以考虑采用原生写法)
使用场景
- 快速创建一个表单和提交表单数据。
- 需要对表单的控件字段进行输入校验。
BasicForm 的 schemas 配置介绍
1. 基本用法
Helllo World第一个入门例子
快速渲染一个表单域,表单域可以是输入控件,标签,下拉菜单,文本域等。 本例:创建一个登录表单,使用户输入用户名,密码后进行登录
- 页面效果
- 示例代码
通过自定义
FormSchema
的字段,并绑定到useForm
中的schemas
参数,就渲染出了一个简单的登录表单
字段定义的映射关系如下:

<!-- 基本用法 -->
<template>
<!-- 自定表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 50px; margin-left: 50px" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
//标题名称
label: '用户名(后面根据labelLength定义的长度隐藏)',
//字段
field: 'username',
//组件 支持组件详见 components/Form/src/types/index.ts 中的 ComponentType
component: 'Input',
//标题宽度,支持数字和字符串
labelWidth: 150,
//标题长度,超过位数隐藏
labelLength: 3,
//一列占比总共24,比如一行显示2列
colProps: { span: 12 },
},
{
label: '密码',
field: 'password',
//子标题名称(在主标题后面)
subLabel: '(数字和字母组成)',
component: 'InputPassword',
labelWidth: '150px',
//一列占比总共24,比如一行显示2列
colProps: { span: 12 },
},
];
/**
* BasicForm绑定注册;
* useForm 是整个框架的核心用于表单渲染,里边封装了很多公共方法;
* 支持(schemas: 渲染表单列,autoSubmitOnEnter:回车提交,submitButtonOptions:自定义按钮文本和图标等方法);
* 平台通过此封装,简化了代码,支持自定义扩展;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
//回车提交
autoSubmitOnEnter: true,
//不显示重置按钮
showResetButton: false,
//自定义提交按钮文本和图标
submitButtonOptions: { text: '提交', preIcon: '' },
//查询列占比 24代表一行 取值范围 0-24
actionColOptions: { span: 17 },
});
/**
* 点击提交按钮的value值
* @param values
*/
function handleSubmit(values: any) {
console.log('提交按钮数据::::', values);
}
</script>
<style scoped></style>
2. 演示字典控件使用
页面效果及代码展示
比如“性别”字段 使用了下拉框控件
,设置了下拉项,并设置默认值为 “未知”;
BasicForm封装了很多控件类型,具体见3. 表单控件清单
- 页面效果
- 示例代码
通过
component
设置控件类型; 通过componentProps
的options
来自定义下拉项; 通过defaultValue
来定义默认值;

<!-- 控件属性 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
label: '员工姓名',
field: 'name',
component: 'Input',
componentProps:{
disabled: true
},
defaultValue:'张三'
},
{
label: '性别',
field: 'sex',
component: 'Select',
//填写组件Select的属性
componentProps: {
options: [
{ label: '男', value: 1 },
{ label: '女', value: 2 },
{ label: '未知', value: 3 },
],
},
//默认值
defaultValue: 3,
},
{
label: '年龄',
field: 'age',
component: 'Input',
},
{
label: '入职时间',
field: 'entryTime',
component: 'TimePicker',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>
3 表单控件清单总览
3.1 componentProps基础 占位符的使用
- 页面效果
- 示例代码
①
componentProps
:用于定义组件的属性 ②placeholder
:定义input
属性占位符
<!-- 操作按钮 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" @submit="handleSubmit" style="margin-top: 50px; margin-left: 50px" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { CollapseContainer } from '/@/components/Container';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
//组件的属性(所有组件的属性都要写在componentProps里面)
componentProps: {
//占位符
placeholder:'请输入真实姓名'
},
},
];
/**
* BasicForm绑定注册;
* setProps方法可以动态设置useForm中的属性
*/
const [registerForm, { setProps }] = useForm({
schemas: formSchemas,
//显示操作按钮
showActionButtonGroup: false,
});
</script>
<style scoped></style>
3.2 控件类型详细用法
关于表单控件类型详细用法,请参考表单控件用法示例
名称 | 描述 | componentProps属性 |
---|---|---|
Input | 文本输入框 | Input属性 |
InputGroup | 分组文本输入框 | 采用 插槽 的方式自定义分组文本,和input属性一致,InputGroup独有属性 |
InputPassword | 密码输入框 | 和input属性一致, InputPassword独有属性 |
InputSearch | 文本搜索框 | InputSearch独有属性 |
InputTextArea | 文本域 | 和Input属性一致 |
InputNumber | 数值输入框 | InputNumber属性 |
InputCountDown | 验证码组件 | InputCountDown属性 |
Select | 下拉框组件 | Select属性 |
ApiSelect | Api下拉框组件 | numberToString :是否转成数值,默认为false;api:()=>promise :请求接口;params:{} :请求参数;resultField :返回集合名称;labelField :标题字段名称;valueField :值字段名称;immediate :是否初始化加载,默认true |
TreeSelect | 树下拉选择组件 | TreeSelect属性 |
ApiTreeSelect | 远程Api树下拉选择组件 | 和TreeSelect 返回值须一致,api:()=>promise :请求接口;params:{} :请求参数;resultField :返回集合名称;immediate :是否初始化加载,默认true |
ApiRadioGroup | 远程Api单选框组 组件 | api:()=>promise :请求接口;params:{} :请求参数;isBtn :是否为按钮风格类型,默认false;numberToString :是否转成数值,默认为false;resultField :返回集合名称labelField :标题字段名称;valueField :值字段名称;immediate :是否初始化加载,默认true |
RadioButtonGroup | 单选按钮组 组件 | options :自定义标题和值 |
RadioGroup | 单选框组 组件 | RadioGroup属性 |
Checkbox | 多选框组件 | Checkbox属性 |
CheckboxGroup | 多选框组 组件 | CheckboxGroup属性 |
AutoComplete | 自动完成组件 | AutoComplete属性 |
Cascader | 级联选择组件 | Cascader属性 |
DatePicker | 日期选择框组件 | DatePicker属性 |
MonthPicker | 月份选择组件 | - |
WeekPicker | 日期选择组件 | - |
TimePicker | 时间选择组件 | - |
RangePicker | 日期时间范围选择组件 | RangePicker属性 |
RangeDate | 日期范围选择组件 | - |
RangeTime | 时间范围选择组件 | - |
Switch | 开关组件 | Switch属性 |
StrengthMeter | 密码组件 | showInput :是否显示密码输入框,默认为true;disabled:是否禁用,默认false |
Slider | 滑动滚动条组件 | Slider属性 |
Rate | 评分组件 | Rate属性 |
Divider | 分割线组件 | Divider属性 |
JAreaLinkage | 省市县联动组件 | JAreaLinkage属性 |
JSelectPosition | 岗位选择组件 | JSelectPosition属性 |
JSelectRole | 角色选择组件 | JSelectRole属性 |
JSelectUser | 用户选择组件 | JSelectUser属性 |
JImageUpload | 图片上传组件 | JImageUpload属性 |
JDictSelectTag | 自定标签组件 | JDictSelectTag属性 |
JSelectDept | 选择部门组件 | JSelectDept属性 |
JAreaSelect | 省市级联动组件 | JAreaSelect属性 |
JEditor | 富文本组件 | JEditor属性 |
JMarkdownEditor | markdown组件 | JMarkdownEditor属性 |
JSelectInput | 可输入下拉框组件 | JSelectInput属性 |
JCodeEditor | 代码编辑器组件 | height :高度,字符串类型,默认值auto ;disabled :是否禁用,默认false;fullScreen :是否全屏,默认false;zIndex :全屏之后的index;theme :代码主题,如html ;language :语言;keywords :代码提示 |
JCategorySelect | 分类字典树组件 | JCategorySelect属性 |
JSelectMultiple | 下拉多选组件 | JSelectMultiple属性 |
JPopup | 弹窗选择组件 | JPopup属性 |
JSwitch | 开关组件 | JSwitch属性 |
JEasyCron | 定时表达式选择组件 | JEasyCron属性 |
JTreeDict | 分类字典树形组件 | JTreeDict属性 |
JInputPop | 多行输入窗口组件 | JInputPop属性 |
JCheckbox | 多选组件 | JCheckbox属性 |
JInput | 特殊查询组件 | JInput属性 |
JTreeSelect | 下拉树选择组件 | JTreeSelect属性 |
JSelectUserByDept | 根据部门选择用户组件 | JSelectUserByDept属性 |
JUpload | 上传组件 | JUpload属性 |
JSearchSelect | 字典表的搜索组件 | JSearchSelect属性 |
JAddInput | 动态创建input框 | value :绑定的值; min :列表上存在几条数据,删除按钮才会显示,数值类型,默认值位1 |
UserSelect | 用户选择组件 | UserSelect属性 |
RoleSelect | 选择角色组件 | RoleSelect属性 |
JRangeNumber | 数值范围输入框 | - |
4. 组件的显示、隐藏与动态禁用
场景一:我们可以将id隐藏,让其不在页面上显示,但是编程使用。 场景二:当单选按钮 “对公司整体评价”
- 选择满意的时候,隐藏不满意说明;
- 选择不满意的时候,需要填写不满意原因说明,并将满意度禁用
- 页面效果
- 示例代码
默认静态隐藏id,满意时满意度可以拖动

“对公司整体评价”选择不满意的时候,需要填写不满意原因说明,并且满意度不可拖动

使用
show
或者ifShow
属性来控制表单组件的显示和隐藏

使用
dynamicDisabled
动态控制表单组件禁用

<!-- 字段显示与隐藏 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'id',
label: '编号',
component: 'Input',
//隐藏id,css 控制,不会删除 dom(支持布尔类型 true和false。支持动态值判断,详情请见ifShow)
show: false,
},
{
field: 'evaluate',
label: '对公司整体评价',
component: 'RadioGroup',
componentProps: {
options: [
{ label: '满意', value: '0' },
{ label: '不满意', value: '1' },
],
},
defaultValue: '0',
},
{
field: 'describe',
label: '不满意原因说明',
component: 'InputTextArea',
//ifShow和show属性一致,values代表当前表单的值,js 控制,会删除 dom
ifShow: ({ values }) => {
return values.evaluate == '1';
},
},
{
field: 'satisfiedLevel',
label: '满意度',
component: 'Slider',
componentProps: {
tipFormatter: (value) => {
return value + '%';
},
},
//动态禁用,values代表当前表单的值,返回 true或false
dynamicDisabled: ({ values }) => {
return values.evaluate == '1';
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>
5. 内容提示与组件后缀
- 场景一:对当前月份加上后缀月
- 场景二:对迟到次数提示当前迟到几次,罚款多少元
5.1 页面效果及代码展示
- 页面效果
- 示例代码


使用
suffix
属性,完成组件后缀的提示
使用
helpMessage
提示帮助信息

可以使用
helpComponentProps
修改提示信息的样式

<!-- 字段标题提示及前缀 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'month',
label: '当前月份',
component: 'Input',
suffix: '月',
},
{
field: 'lateNumber',
label: '迟到次数',
component: 'InputNumber',
//帮助信息:可以直接返回String(helpMessage:"迟到次数"),也可以获取表单值,动态填写
helpMessage: ({ values }) => {
return '当前迟到次数' + values.lateNumber + ', 扣款' + values.lateNumber * 50 + '元';
},
defaultValue: 0,
},
{
field: 'lateReason',
label: '迟到原因',
component: 'Input',
helpMessage: '什么原因耽误上班迟到',
//自定义提示属性,需要结合helpMessage一起使用
helpComponentProps: {
maxWidth: '200px',
color: '#66CCFF',
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped></style>
5.2 helpComponentProps
的属性介绍
//最大宽度
maxWidth: string;
//是否显示序号
showIndex: boolean;
//文本列表,会覆盖helpMessage定义的文本
text: any;
//颜色
color: string;
//字体大小
fontSize: string;
//气泡框位置
placement: string;
6. 表单检验
对只有通过检验的表单才允许保存。例:对来访人员表单进行检验
- 页面效果
- 示例代码
触发表单验证效果

-
① 填写
required
完成自动表单检验,rulesMessageJoinLabel
是否加上标题 -
②
required
支持获取当前值判断触发 values代表当前表单的值 -
③ 支持正则表达式pattern 和 自定义提示信息 message,使用属性
rules
即可
<!-- 表单验证 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px" @submit="handleSubmit" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
//自动触发检验,布尔类型
required: true,
//检验的时候不加上标题
rulesMessageJoinLabel: false,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
//支持获取当前值判断触发 values代表当前表单的值
required: ({ values }) => {
return !values.accessed;
},
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
//支持正则表达式pattern 和 自定义提示信息 message
rules: [{ required: false, message: '请输入正确的手机号', pattern: /^1[3456789]\d{9}$/ }],
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交事件
*/
function handleSubmit(values: any) {}
</script>
<style scoped></style>
7. 自定义动态表单检验
- 对"来访手机号" 没有填写的时候提示请输入手机号
- 手机号填写不正确提示请输入正确的手机号。
- 页面效果
- 示例代码
手机号无值

手机号有值,但是手机号不正确

手机号验证通过

主要根据
schemas
属性动态检验dynamicRules

<!-- 动态表单验证 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px" @submit="handleSubmit" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import { duplicateCheck } from '/@/views/system/user/user.api';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'visitor',
label: '来访人员',
component: 'Input',
//自动触发检验,布尔类型
required: true,
},
{
field: 'accessed',
label: '来访日期',
component: 'DatePicker',
//支持获取当前值判断触发 values代表当前表单的值
required: ({ values }) => {
return !values.accessed;
},
},
{
field: 'phone',
label: '来访人手机号',
component: 'Input',
//动态自定义正则,values: 当前表单的所有值
dynamicRules: ({ values }) => {
console.log('values:', values);
//需要return
return [
{
//默认开启表单检验
required: true,
// value 当前手机号输入的值
validator: (_, value) => {
//需要return 一个Promise对象
return new Promise((resolve, reject) => {
if (!value) {
reject('请输入手机号!');
}
//验证手机号是否正确
let reg = /^1[3456789]\d{9}$/;
if (!reg.test(value)) {
reject('请输入正确手机号!');
}
resolve();
});
},
},
];
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交事件
*/
function handleSubmit(values: any) {}
</script>
<style scoped></style>
8. 字段插槽slot
简单使用
例:在收集用户反馈中,下方提示文本信息,以便用户理解并填写
- 页面效果
- 示例代码

在
shemes
中我们可以通过slot
进行绑定,并在BasicForm
中填写对应插槽的名称

<!-- 插槽 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px">
<!-- #phone对应的是formSchemas对应slot(phone)插槽 -->
<template #phone="{ model, field }">
<!-- 如果是组件需要进行双向绑定,model当前表单对象,field当前字段名称 -->
<a-input v-model:value="model[field]" placeholder="请输入手机号" />
<span class="font-color">请输入您的手机号,方便我们联系您</span>
</template>
<template #feedback="{ model, field }">
<JEditor v-model:value="model[field]" placeholder="请输入问题反馈" />
<span class="font-color">请您图文并茂,方便我们了解问题并及时反馈</span>
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
},
{
field: 'phone',
label: '联系方式',
component: 'Input',
slot: 'phone',
},
{
field: 'feedback',
label: '问题反馈',
component: 'InputTextArea',
slot: 'feedback',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped>
.font-color {
font-size: 13px;
color: #a1a1a1;
margin-bottom: 5px;
}
</style>
9. 自定义组件
自定义组件分为两种方式
slot
插槽方式component
方式
9.1 slot插槽方式
- 页面效果
- 示例代码

在
shemes
中我们可以通过slot
进行绑定,并在BasicForm
中填写对应插槽的名称

一般我们放在
src/components/Form/src/jeecg
目录下,本示例自定义组件名称为CustomDemo

<template>
<a-input v-model:value="innerValue" @change="handleChange">
<template #addonAfter>
<a-icon type="setting" @click="handleIconClick" style="cursor: pointer"></a-icon>
</template>
</a-input>
</template>
<script lang="ts">
import { defineComponent, watch, ref } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({
name: 'CustomDemo',
props: {
value: propTypes.string.def(''),
},
emits: ['change', 'update:value'],
setup(props, { emit }) {
const { createMessage } = useMessage();
const innerValue = ref<any>('');
//监听value变化
watch(
() => props.value,
(val) => {
innerValue.value = val;
},
{ immediate: true }
);
/**
* 设置按钮点击事件
*/
function handleIconClick() {
createMessage.success('当前值:' + innerValue.value);
}
/**
* change事件
* @param e
*/
function handleChange(e) {
let value = e.target.value;
emit('update:value', value);
emit('change', value);
}
return {
innerValue,
handleIconClick,
handleChange,
};
},
});
</script>
<style scoped></style>
组件引用
<!-- 插槽 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px" @submit="handleSubmit">
<!-- #name对应的是formSchemas对应slot(name)插槽 -->
<template #name="{ model, field }">
<CustomDemo v-model:value="model[field]" />
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//引入CustomDemo自定义组件
import CustomDemo from '/@/components/Form/src/jeecg/demo/CustomDemo.vue'
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'name',
label: '姓名',
component: 'Input',
slot:'name'
},
{
field: 'phone',
label: '联系方式',
component: 'Input',
},
{
field: 'feedback',
label: '问题反馈',
component: 'InputTextArea',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
/**
* 提交信息
*/
function handleSubmit(values) {
console.log("values::",values);
}
</script>
<style scoped>
.font-color {
font-size: 13px;
color: #a1a1a1;
margin-bottom: 5px;
}
</style>
9.2 component方式
- 页面效果
- 示例代码

一般我们放在
src/components/Form/src/jeecg
目录下,本示例自定义组件名称为CustomDemo

<template>
<a-input v-model:value="innerValue" @change="handleChange">
<template #addonAfter>
<a-icon type="setting" @click="handleIconClick" style="cursor: pointer"></a-icon>
</template>
</a-input>
</template>
<script lang="ts">
import { defineComponent, watch, ref } from 'vue';
import { useMessage } from '/@/hooks/web/useMessage';
import { propTypes } from '/@/utils/propTypes';
export default defineComponent({
name: 'CustomDemo',
props: {
value: propTypes.string.def(''),
},
emits: ['change', 'update:value'],
setup(props, { emit }) {
const { createMessage } = useMessage();
const innerValue = ref<any>('');
//监听value变化
watch(
() => props.value,
(val) => {
innerValue.value = val;
},
{ immediate: true }
);
/**
* 设置按钮点击事件
*/
function handleIconClick() {
createMessage.success('当前值:' + innerValue.value);
}
/**
* change事件
* @param e
*/
function handleChange(e) {
let value = e.target.value;
emit('update:value', value);
emit('change', value);
}
return {
innerValue,
handleIconClick,
handleChange,
};
},
});
</script>
<style scoped></style>
全局引入:路径
src/components/Form/src/componentMap.ts

import CustomDemo from './jeecg/demo/CustomDemo.vue';
componentMap.set('CustomDemo',CustomDemo);
在
ComponentType
中引入自定义组件,路径src/components/Form/src/types/index.ts

| 'CustomDemo'
组件中引入

<!-- 自定义组件 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin-top: 50px; margin-left: 50px" />
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'custom',
label: '自定义组件',
//引入自定义组件
component: 'CustomDemo',
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showActionButtonGroup: false,
});
</script>
<style scoped></style>
10. 自定义渲染
例:商品描述需要商品名称加上价格乘以数量
- 页面效果
- 示例代码
- ① 自定义组件 input输入框
- ② 商品名称加上价格乘以价格

① 自定义渲染组件

② 自定义文本渲染

<!-- 自定义渲染 -->
<template>
<!-- 自定义表单 -->
<BasicForm @register="registerForm" style="margin: 50px 50px 0 50px">
<!-- #phone对应的是formSchemas对应slot(phone)插槽 -->
<template #phone="{ model, field }">
<!-- 如果是组件需要进行双向绑定,model当前表单对象,field当前字段名称 -->
<a-input v-model:value="model[field]" placeholder="请输入手机号" />
<span class="font-color">请输入您的手机号,方便我们联系您</span>
</template>
<template #feedback="{ model, field }">
<JEditor v-model:value="model[field]" placeholder="请输入问题反馈" />
<span class="font-color">请您图文并茂,方便我们了解问题并及时反馈</span>
</template>
</BasicForm>
</template>
<script lang="ts" setup>
//引入依赖
import { useForm, BasicForm, FormSchema } from '/@/components/Form';
import JEditor from '/@/components/Form/src/jeecg/components/JEditor.vue';
import { h } from 'vue';
import { Input } from 'ant-design-vue';
//自定义表单字段
const formSchemas: FormSchema[] = [
{
field: 'productName',
label: '商品名称',
component: 'Input',
},
{
field: 'price',
label: '价格',
component: 'InputNumber',
},
{
field: 'buyNums',
label: '购买个数',
component: 'InputNumber',
//model 单签表单对象,field 当前字段
render: ({ model, field }) => {
//渲染自定义组件,以Input为例
return h(Input, {
placeholder: '请输入购买个数',
value: model[field],
style: { width: '100%' },
type: 'number',
onChange: (e: ChangeEvent) => {
model[field] = e.target.value;
},
});
},
},
{
field: 'describe',
label: '描述',
component: 'Input',
componentProps: {
disabled: true,
},
//渲染 values当前表单所有值
render: ({ values }) => {
let productName = values.productName;
let price = values.price ? values.price : 0;
let buyNums = values.buyNums ? values.buyNums : 0;
return '购买商品名称:' + productName + ', 总价格: ' + price * buyNums + '元';
},
},
];
/**
* BasicForm绑定注册;
*/
const [registerForm] = useForm({
//注册表单列
schemas: formSchemas,
showResetButton: false,
submitButtonOptions: { text: '提交', preIcon: '' },
actionColOptions: { span: 17 },
});
</script>
<style scoped>
/** 数字输入框样式 */
:deep(.ant-input-number) {
width: 100%;
}
</style>
schemas
api属性
属性 | 类型 | 默认值 | 可选值 | 说明 |
---|---|---|---|---|
field | string | - | - | 字段名 |
label | string () => string 3.7.1+ | - | - | 标签名 |
subLabel | string | - | - | 二级标签名灰色 |
suffix | string , number , ((values: RenderCallbackParams) => string / number); | - | - | 组件后面的内容 |
changeEvent | string | - | - | 表单更新事件名称 |
helpMessage | string , string[] | - | - | 标签名右侧温馨提示,见 4. 内容提示与组件后缀 |
helpComponentProps | HelpComponentProps | - | - | 标签名右侧温馨提示组件,见 4. 内容提示与组件后缀 |
labelWidth | string , number | - | - | 覆盖统一设置的 labelWidth |
disabledLabelWidth | boolean | false | true/false | 禁用 form 全局设置的 labelWidth,自己手动设置 labelCol 和 wrapperCol |
component | string | - | - | 组件类型,见 1.基本用法 |
componentProps | any,()=> | - | - | 所渲染的组件的 props |
rules | ValidationRule[] | - | - | 校验规则,见 5.表单检验 |
required | boolean | - | - | 开启表单验证 |
rulesMessageJoinLabel | boolean | false | - | 校验信息是否加入 label |
itemProps | any | - | - | 注入到FormItem的属性 |
colProps | ColEx | - | - | 组件占位比例,如colProps: { span: 18 } |
defaultValue | object | - | - | 所渲渲染组件的初始值 |
render | (renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string | - | - | 自定义渲染组件 |
renderColContent | (renderCallbackParams: RenderCallbackParams) => VNode / VNode[] / string | - | - | 自定义渲染组件(需要自行包含 formItem) |
renderComponentContent | (renderCallbackParams: RenderCallbackParams) => any / string | - | - | 自定义渲染组内部的 slot |
slot | string | - | - | 自定义 slot,渲染组件 |
colSlot | string | - | - | 自定义 slot,渲染组件 (需要自行包含 formItem |
show | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判断当前组件是否显示,css 控制,不会删除 dom |
ifShow | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判断当前组件是否显示,js 控制,会删除 dom |
dynamicDisabled | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判断当前组件是否禁用 |
dynamicRules | boolean / ((renderCallbackParams: RenderCallbackParams) => boolean) | - | - | 动态判返当前组件你校验规则 |
dynamicPropskey | string | - | - | 设置需要动态更新值对应的key (必须搭配dynamicPropsVal使用) |
dynamicPropsVal | ((renderCallbackParams: RenderCallbackParams) => any) | - | - | 动态更新当前组件props(必须搭配dynamicPropskey使用) |