快捷表单 · 基础篇
概述
Jiess Plus 的快捷表单系统基于 BuildArea + ItemBuilder 架构,提供跨框架统一的表单组件:
| 组件 | 说明 | Vue3 Element | Vue3 Vant | React Antd |
|---|---|---|---|---|
$Input | 文本输入框 | ✅ | ✅ | ✅ |
$InputNumber | 数字输入 | ✅ | — | ✅ |
$Select | 下拉选择器 | ✅ | ✅ | ✅ |
$DatePicker | 日期选择器 | ✅ | ✅ | ✅ |
$TimePicker | 时间选择器 | ✅ | — | ✅ |
$Switch | 开关 | ✅ | ✅ | ✅ |
$CheckboxGroup | 复选框组 | ✅ | ✅ | ✅ |
$RadioGroup | 单选框组 | ✅ | — | ✅ |
$TreeSelect | 树形选择器 | ✅ | ✅ | ✅ |
$Cascader | 级联选择器 | ✅ | ✅ | ✅ |
$ColorPicker | 颜色选择器 | ✅ | — | ✅ |
框架特化文档: ElementPlus 表单 | Vant 表单 | AntDesign 表单
基本用法
javascript
import { $Input, $Select, $Switch } from '@jiess/plus/vue3';
// 每个表单组件接受一个配置对象
$Input({
$label: '姓名', // 标签($ 开头:Jiess 内置)
$name: 'name', // 字段名(用于提交/校验)
$rules: ['required'], // 校验规则名(见下方校验规则章节)
placeholder: '请输入姓名', // 透传给底层 UI 组件
clearable: true,
});
$Select({
$label: '性别',
$name: 'gender',
options: [ // 选项(非 $ 开头:透传)
{ label: '男', value: 'male' },
{ label: '女', value: 'female' },
],
});
$Switch({
$label: '启用',
$name: 'enabled',
$value: true, // 默认值
});配置对象规范
| 前缀 | 含义 | 示例 |
|---|---|---|
$ | Jiess 内置属性 | $label, $name, $rules, $value |
$$ | Jiess 内部保留 | $$validate, $$ref |
| 无前缀 | 透传给底层 UI 组件 | placeholder, clearable, maxLength |
校验规则(RuleManger)
@jiess/plus 内置 14 条校验规则,在 RuleManger.getBuiltinRules() 中定义。
内置规则列表
| 规则名 | 说明 | 示例用法 |
|---|---|---|
required | 必填校验 | $rules: ['required'] |
range | 字符串长度范围 | $rules: [['range', 2, 10]] |
requireArr | 数组非空(过滤 null/undefined) | $rules: ['requireArr'] |
email | 邮箱格式(支持中文邮箱) | $rules: ['email'] |
phone | 手机号格式(主流号段) | $rules: ['phone'] |
mark | 标识格式(字母/数字/下划线/中横线) | $rules: ['mark'] |
number | 纯数字 | $rules: ['number'] |
card | 身份证(18 位含校验码 + 15 位) | $rules: ['card'] |
url | URL 格式(http/https) | $rules: ['url'] |
ip | IPv4 地址 | $rules: ['ip'] |
chinese | 必须包含中文 | $rules: ['chinese'] |
noChinese | 不能包含中文 | $rules: ['noChinese'] |
positiveInt | 正整数(不含 0) | $rules: ['positiveInt'] |
decimal | 合法数值(含负数/小数) | $rules: ['decimal'] |
使用示例
javascript
$Input({ $label: '身份证号', $name: 'idCard', $rules: ['required', 'card'] })
$Input({ $label: '网站', $name: 'website', $rules: ['url'] })
$Input({ $label: '服务器IP', $name: 'host', $rules: ['required', 'ip'] })
$Input({ $label: '数量', $name: 'qty', $rules: ['positiveInt'] })
$Input({ $label: '价格', $name: 'price', $rules: ['decimal'] })数组形式的特殊参数
javascript
// range 规则需要传参:[规则名, 最小值, 最大值]
$Input({ $label: '用户名', $name: 'username', $rules: [['range', 2, 10]] })
// 等价于:长度在 2 到 10 之间自定义校验规则
通过 globalConfig._ruleConfig.ruleData 注入:
javascript
const hook = $initHook({
globalConfig: {
_ruleConfig: {
ruleData: {
// 校验函数格式:(value, label) => string | undefined
password: (value, label) => {
if (!value || value.length < 6) return `${label} 不能少于6位`;
if (!/[A-Z]/.test(value)) return `${label} 必须包含大写字母`;
},
maxLength100: (value, label) => {
if (value && value.length > 100) return `${label} 不能超过100个字符`;
},
},
},
},
});javascript
// 使用注入的规则
$Input({ $label: '密码', $name: 'password', $rules: ['required', 'password'] })
$Input({ $label: '备注', $name: 'remark', $rules: ['maxLength100'] })注意:如果注入的规则名与内置规则重名(如注入一个
Area 级校验配置
Jiess Plus 的校验系统分为两层:
| 层级 | 配置位置 | 作用 |
|---|---|---|
| Area 级 | $Area({ ruleConfig, hasRule }) | 控制是否启用校验、注入自定义规则、覆盖提示文案 |
| Item 级 | $Input({ $rules: [...] }) | 声明具体字段使用的规则 |
ruleConfig 配置项
javascript
$Area({
ruleConfig: {
// 自定义规则注入(与 globalConfig._ruleConfig.ruleData 效果相同,但作用域限于当前 Area)
rules: {
customRule: (value, label) => value === 'admin' ? `${label}不能是admin` : true
},
// 全局规则提示文案覆盖
messages: {
required: (label) => `请输入${label}`,
email: (label) => `${label}格式不正确`
}
},
hasRule: true // 默认 true,设为 false 跳过该 Area 的所有校验
})$rules 函数形式
除数组形式外,$rules 还支持函数形式,接收 rule(RuleManger 实例)和 $label:
javascript
$Input({
$label: '用户名',
$name: 'username',
$rules: (rule, $label) => [
rule.required($label),
rule.customRule($label) // 使用 area 级注入的自定义规则
]
})优势:函数形式可在运行时动态决定规则组合,并直接调用 area 级注入的规则,无需通过字符串名引用。
表单布局
内联表单
javascript
{
$Form: {
layout: 'inline',
children: {
keyword: { $Input: { $label: '关键词' } },
status: { $Select: { $label: '状态', options: [...] } },
$Button: { children: '搜索', type: 'primary' },
},
},
}表单项并排
javascript
{
$Form: {
children: {
$Row: {
children: {
name: { $Input: { $label: '姓名' } },
email: { $Input: { $label: '邮箱' } },
},
},
},
},
}获取表单数据
javascript
// 在 $JiessTable 或 $JiessDialog 的 render 函数中
render(midder, context) {
// 获取表单所有值
const data = this.area.nameManger.getData();
// 校验表单
const isValid = await this.area.nameManger.validate();
// 重置表单
this.area.nameManger.reset();
}进阶场景
场景1:表单联动(A 选择影响 B 的选项)
表单联动是后台管理中最常见的需求之一。以下通过 onChange 事件实现省市区三级联动:
javascript
import { $Select } from '@jiess/plus/vue3';
// 省份数据
const provinceOptions = [
{ label: '广东省', value: '440000' },
{ label: '浙江省', value: '330000' },
];
export default {
province: {
$Select: {
$label: '省份',
$name: 'province',
$rules: [{ required: true, message: '请选择省份' }],
options: provinceOptions,
filterable: true,
// 核心:监听 onChange 触发联动
onChange(val) {
// 1. 更新城市选项
this.$update.city.options = getCityByProvince(val);
// 2. 清空已选的城市和区县
this.area.nameManger.setFieldValue('city', null);
this.area.nameManger.setFieldValue('district', null);
},
},
},
city: {
$Select: {
$label: '城市',
$name: 'city',
$rules: [{ required: true, message: '请选择城市' }],
options: [], // 初始为空,省份选择后填充
filterable: true,
onChange(val) {
this.$update.district.options = getDistrictByCity(val);
this.area.nameManger.setFieldValue('district', null);
},
},
},
district: {
$Select: {
$label: '区县',
$name: 'district',
options: [], // 初始为空
filterable: true,
},
},
};场景2:动态表单项(增删行)
适用于问卷调查、动态配置等需要动态增删表单项的场景:
javascript
// 在响应式上下文中管理动态行数据
const formItems = $reactive({
items: [{ value: '' }], // 初始一行
});
// 生成动态表单配置
const dynamicFormConfig = computed(() => {
// 将 formItems.items 映射为表单字段
const fields = {};
formItems.items.forEach((item, idx) => {
fields[`item_${idx}`] = {
$Input: {
$label: `项目 ${idx + 1}`,
$name: `items[${idx}]`,
placeholder: `请输入内容`,
clearable: true,
// 一行以内的字段可以并排
},
};
});
// 添加操作按钮
fields.$tools = {
$Space: {
children: [
{
$Button: {
children: '添加一行',
type: 'primary',
onClick() {
formItems.items.push({ value: '' });
},
},
},
{
$Button: {
children: '删除最后一行',
type: 'danger',
onClick() {
if (formItems.items.length > 1) {
formItems.items.pop();
}
},
},
},
],
},
};
return { $Form: { children: fields } };
});场景3:表单数据回填(编辑场景)
编辑已有数据时,通过 $value 属性回填表单:
javascript
// 从接口获取数据后,构造回填配置
async function getEditConfig(userId) {
const userData = await fetch(`/api/users/${userId}`).then(r => r.json());
return {
$Form: {
children: {
name: {
$Input: {
$label: '姓名',
$name: 'name',
$value: userData.name, // 回填文本值
$rules: [{ required: true }],
},
},
email: {
$Input: {
$label: '邮箱',
$name: 'email',
$value: userData.email, // 回填文本值
$rules: [{ email: true }],
},
},
status: {
$Select: {
$label: '状态',
$name: 'status',
$value: userData.status, // 回填选择值
options: [
{ label: '启用', value: 1 },
{ label: '禁用', value: 0 },
],
},
},
birthday: {
$DatePicker: {
$label: '生日',
$name: 'birthday',
$value: userData.birthday, // 回填日期值
type: 'date',
},
},
active: {
$Switch: {
$label: '启用',
$name: 'active',
$value: userData.active, // 回填布尔值
},
},
},
},
};
}注意事项
| 事项 | 说明 |
|---|---|
required 与其他规则组合 | $rules: ['required', 'card'] 先验证必填,再验证格式 |
card 校验码验证 | 18 位身份证执行 GB 11643-1999 校验码算法(加权求和→查表) |
range 用法特殊 | 带参数的规则用数组形式:[['range', min, max]] |
| 自定义函数规则 | $rules: [(value, label) => '错误消息'] 也可直接传函数 |
| 校验触发时机 | 默认 trigger: ['blur', 'submit'](失焦 + 提交时触发) |
下一步
- 框架特化文档: ElementPlus 表单 | Vant 表单 | AntDesign 表单
- 全局弹框-基础.md —— 弹框内嵌表单
- 高级特性 ——
start()注入、校验规则合并机制