Skip to content

快捷表单 · 基础篇 ​

概述 ​

Jiess Plus 的快捷表单系统基于 BuildArea + ItemBuilder 架构,提供跨框架统一的表单组件:

组件说明Vue3 ElementVue3 VantReact 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']
urlURL 格式(http/https)$rules: ['url']
ipIPv4 地址$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'] })

注意:如果注入的规则名与内置规则重名(如注入一个 email),会覆盖内置规则。不建议这样做。


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'](失焦 + 提交时触发)

下一步 ​