表单页设计
云控专属可视化开发工具
- 全网独家定制
- 数据私有化部署
- 支持多级菜单管理
- 多用户分级管理
- 二次开发成本直降80%
全局方法
提供两个用于获取表单数据的全局方法:
| 方法名 | 说明 |
|---|---|
get[formName]ControlByName(name) | 根据字段 name 获取表单项(完整数据对象) |
get[formName]ValueByName(name) | 根据字段 name 获取表单项的值 |
说明
formName:表单名称(动态拼接)name:表单字段唯一标识Control:返回完整字段对象(包含 label、type、value 等)Value:仅返回字段值,多用于跨字段取值、表单联动及复杂校验场景(如确认密码校验)
表单 opt 配置
opt = {
list: [...], // 字段配置
form: {...}, // 表单配置
events: {...}, // 事件
config: {...} // 表单接口行为配置
}
字段列表 (list)
每个字段对象包含以下属性:
| 属性名 | 说明 | 类型 | 是否必填 | 默认值 |
|---|---|---|---|---|
type | 组件类型 | string | 是 | — |
name | 字段名(唯一标识) | string | 是 | — |
control | 组件属性配置 | object | 是 | {} |
formItem | 表单项配置(标签、校验规则) | object | 否 | {} |
customRules | 自定义校验规则 | array | 否 | [] |
config | 扩展配置(远程数据、联动等) | object | 否 | {} |
{
type: "input", // 组件类型,固定为 input
name: "username", // 字段名,绑定数据用的 key
control: {
modelValue: "", // 绑定的输入值,双向绑定
type: "text", // 输入框类型,如 text、password 等
placeholder: "请输入用户名", // 输入框占位提示文字
maxlength: 20, // 最大输入长度
minlength: 3, // 最小输入长度
showWordLimit: true, // 是否显示字数统计
clearable: true, // 是否显示清除按钮
disabled: false, // 是否禁用输入框
readonly: false, // 是否只读
autocomplete: "off", // 浏览器自动完成功能,off 禁用
autofocus: false, // 是否自动聚焦
tabindex: "1", // tab 键顺序
validateEvent: true, // 是否触发表单验证事件
inputStyle: { // 输入框自定义样式
color: "#333", // 字体颜色
fontSize: "14px" // 字体大小
},
size: "default", // 输入框尺寸,可选 small、default、large
options: [ // 选项数组,常用于 select、radio、checkbox 等
{ label: "选项1", value: "1" }, // 选项 label 和 value
{ label: "选项2", value: "2" }
],
multiple: false, // 是否多选,select 组件常用
filterable: true, // 是否支持搜索筛选,select 组件常用
rows: 4, // 多行文本框行数,textarea 专用
resize: "vertical", // textarea 是否允许调整大小及方向
autosize: { // textarea 自动高度配置
minRows: 2, // 最小行数
maxRows: 6 // 最大行数
},
buttonStyle: "outline", // radio 按钮样式
min: 0, // 输入数字类组件最小值,如 inputNumber、slider
max: 100, // 最大值
step: 1, // 步长
format: "yyyy-MM-dd", // 日期格式,datePicker 专用
placeholderTime: "选择时间", // 时间选择器占位提示
disabledDate: (date) => date < new Date(), // 禁用日期函数,禁止选择今天之前日期
showAlpha: false, // 颜色选择器是否显示透明度
activeColor: "#409EFF", // 颜色选择器主题色
checked: false, // 开关状态,switch 组件专用
icon: "Check", // 按钮图标名
loading: false, // 按钮加载状态
text: "提交", // 按钮文本
columns: [ // 表格列配置
{ label: "姓名", prop: "name" },
{ label: "年龄", prop: "age" }
],
data: [], // 表格数据
style: { // 容器样式
padding: "10px", // 内边距
backgroundColor: "#f5f5f5" // 背景颜色
},
height: 300, // 富文本编辑器高度
action: "/upload", // 上传接口地址
multipleUpload: false, // 是否支持多文件上传
showFileList: true // 是否显示文件列表
},
formItem: {
label: "确认密码", // 表单标签
rules: [
{
validator: (rule, value, callback) => { // 自定义验证函数
if (value === "") {
callback(new Error("请输入确认密码")); // 不符合规则时传入错误信息
} else {
const password = getform1ValueByName("password"); // 获取其他字段值进行校验
if (password === value) {
callback(); // 校验通过
} else {
callback(new Error("两次密码输入不一致")); // 校验失败错误提示
}
}
},
trigger: "blur" // 触发校验的时机
}
]
},
customRules: [
{
type: "required", // 必填规则类型
message: "必填项", // 提示信息
trigger: "blur" // 触发校验时机
}
],
config: {
optionsType: 1, // 自定义配置项类型
optionsFun: "demo/options", // 远程接口或本地方法名
method: "get", // 请求方法
linkage: "name1", // 关联的其他组件字段名
before: (params, { type, route, model }) => { // 请求前钩子,修改参数
console.log(type);
return params;
},
after: (res, success, type) => { // 请求后钩子,处理结果
console.log(type, res);
return res;
}
}
}
type 组件类型
{string}组件类型标识(必填)
组件类型用于标识当前表单项的类型,固定字符串,不可为空。
支持类型:
input:单行文本textarea:多行文本radio:单选框checkbox:多选框select:下拉选择datePicker:日期选择器timePicker:时间选择器colorPicker:颜色选择器switch:开关inputNumber:数字输入框cascader:级联选择器rate:评分slider:滑块treeSelect:树选择txt:文本展示title:标题tabs:标签页flex:布局容器card:卡片divider:分割线button:按钮table:表格component:自定义组件upload:上传tinymce:富文本编辑器grid:栅格布局div:普通容器
input(单行文本)
用于输入标题、名称、链接、UID 等简单字符串信息。
🔸type
固定值:"input"(单行文本输入组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的输入值 | string | number | "" |
| type | 输入框类型(text 等) | string | "text" |
| placeholder | 输入框占位提示文字 | string | "" |
| maxlength | 最大输入长度 | number | — |
| minlength | 最小输入长度 | number | — |
| showWordLimit | 是否显示字数统计 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| disabled | 是否禁用输入框 | boolean | false |
| readonly | 是否只读 | boolean | false |
| autocomplete | 浏览器自动完成功能 | string | "off" |
| autofocus | 是否自动聚焦 | boolean | false |
| tabindex | tab 键顺序 | string | number | — |
| validateEvent | 是否触发表单验证事件 | boolean | true |
| inputStyle | 输入框自定义样式 | object | {} |
| size | 输入框尺寸(small等) | string | "default" |
{
"type": "input",
"name": "username",
"control": {
"modelValue": "",
"type": "text",
"placeholder": "请输入用户名",
"maxlength": 20,
"minlength": 3,
"showWordLimit": true,
"clearable": true,
"disabled": false,
"readonly": false,
"autocomplete": "off",
"autofocus": false,
"tabindex": "1",
"validateEvent": true,
"inputStyle": {},
"size": "default"
},
"formItem": {
"label": "用户名",
"rules": [
{
"validator": (rule, value, callback) => {
if (!/^[a-zA-Z]/.test(value)) {
callback(new Error("必须以字母开头"));
} else {
callback();
}
},
"trigger": "blur"
}
]
},
"customRules": [
{
"required": true,
"message": "请输入用户名",
"trigger": "blur"
},
{
"min": 3,
"max": 20,
"message": "长度在 3 到 20 个字符",
"trigger": "blur"
}
],
"config": {}
}
textarea(多行文本)
用于输入多行文本信息,如备注、评论、详细描述等。
🔸type
固定值:"textarea"(多行文本输入组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的输入值 | string | "" |
| placeholder | 输入框占位提示文字 | string | "" |
| maxlength | 最大输入长度 | number | — |
| minlength | 最小输入长度 | number | — |
| rows | 显示行数 | number | 2 |
| showWordLimit | 是否显示字数统计 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| disabled | 是否禁用输入框 | boolean | false |
| readonly | 是否只读 | boolean | false |
| resize | 是否允许调整大小 | string | "none" |
| autofocus | 是否自动聚焦 | boolean | false |
| validateEvent | 是否触发表单验证事件 | boolean | true |
| inputStyle | 输入框自定义样式 | object | {} |
| size | 输入框尺寸 | string | "default" |
{
"type": "textarea",
"name": "description",
"control": {
"modelValue": "",
"placeholder": "请输入内容",
"maxlength": 500,
"minlength": 5,
"rows": 4,
"showWordLimit": true,
"clearable": true,
"disabled": false,
"readonly": false,
"resize": "vertical",
"autofocus": false,
"validateEvent": true,
"inputStyle": {},
"size": "default"
},
"formItem": {
"label": "描述",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value || value.trim() === "") {
callback(new Error("请输入描述"));
} else {
callback();
}
},
"trigger": "blur"
}
]
},
"customRules": [
{
"required": true,
"message": "请输入描述",
"trigger": "blur"
}
],
"config": {}
}
radio(单选框)
用于在多个选项中选择一个。
🔸type
固定值:"radio"(单选框组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的选中值 | string | number | — |
| options | 选项数组 | Array<{label, value}> | [] |
| disabled | 是否禁用 | boolean | false |
| size | 单选框组尺寸 | string | "default" |
| border | 是否显示边框 | boolean | false |
{
"type": "radio",
"name": "gender",
"control": {
"modelValue": "male",
"options": [
{ "label": "男", "value": "male" },
{ "label": "女", "value": "female" }
],
"disabled": false,
"size": "default",
"border": false
},
"formItem": {
"label": "性别",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value) {
callback(new Error("请选择性别"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择性别",
"trigger": "change"
}
],
"config": {}
}
checkbox(多选框)
用于多选操作,用户可选择多个选项。
🔸type
固定值:"checkbox"(多选框组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的选中值数组 | array | [] |
| options | 选项数组 | Array<{label, value}> | [] |
| disabled | 是否禁用 | boolean | false |
| size | 多选框组尺寸 | string | "default" |
| min | 最小选中数量 | number | — |
| max | 最大选中数量 | number | — |
{
"type": "checkbox",
"name": "hobbies",
"control": {
"modelValue": ["reading", "traveling"],
"options": [
{ "label": "阅读", "value": "reading" },
{ "label": "旅行", "value": "traveling" },
{ "label": "运动", "value": "sports" }
],
"disabled": false,
"size": "default",
"min": 1,
"max": 3
},
"formItem": {
"label": "兴趣爱好",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value || value.length === 0) {
callback(new Error("请选择至少一个爱好"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择至少一个爱好",
"trigger": "change"
},
{
"type": "array",
"min": 1,
"message": "请选择至少一个爱好",
"trigger": "change"
}
],
"config": {}
}
select(下拉选择)
用于从下拉列表中选择一个或多个值。
🔸type
固定值:"select"(下拉选择组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的值(多选时为数组) | string | array | "" |
| options | 选项数组 | Array<{label, value}> | [] |
| multiple | 是否多选 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| placeholder | 占位提示文字 | string | "" |
| filterable | 是否支持搜索过滤 | boolean | false |
| size | 组件尺寸 | string | "default" |
{
"type": "select",
"name": "country",
"control": {
"modelValue": "",
"options": [
{ "label": "中国", "value": "cn" },
{ "label": "美国", "value": "us" },
{ "label": "英国", "value": "uk" }
],
"multiple": false,
"disabled": false,
"clearable": true,
"placeholder": "请选择国家",
"filterable": true,
"size": "default"
},
"formItem": {
"label": "国家",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value) {
callback(new Error("请选择国家"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择国家",
"trigger": "change"
}
],
"config": {}
}
datePicker(日期选择器)
用于选择日期或日期范围。
🔸type
固定值:"datePicker"(日期选择器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的值(范围模式为数组) | string | array | null | null |
| type | 选择器类型 | string | "date" |
| format | 展示格式 | string | — |
| valueFormat | 绑定值格式 | string | — |
| placeholder | 占位提示文字 | string | "" |
| disabled | 是否禁用 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| editable | 输入框是否可编辑 | boolean | true |
| range | 是否为范围选择 | boolean | false |
| size | 组件尺寸 | string | "default" |
{
"type": "datePicker",
"name": "birthday",
"control": {
"modelValue": null,
"type": "date",
"format": "yyyy-MM-dd",
"valueFormat": "yyyy-MM-dd",
"placeholder": "选择日期",
"disabled": false,
"clearable": true,
"editable": true,
"range": false,
"size": "default"
},
"formItem": {
"label": "生日",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value) {
callback(new Error("请选择日期"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择日期",
"trigger": "change"
}
],
"config": {}
}
timePicker(时间选择器)
用于选择时间或时间范围。
🔸type
固定值:"timePicker"(时间选择器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的值(范围模式为数组) | string | array | null | null |
| isRange | 是否为时间范围选择 | boolean | false |
| format | 显示格式 | string | "HH:mm:ss" |
| valueFormat | 绑定值格式 | string | "HH:mm:ss" |
| placeholder | 占位提示文字 | string | "" |
| disabled | 是否禁用 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| size | 组件尺寸 | string | "default" |
{
"type": "timePicker",
"name": "meetingTime",
"control": {
"modelValue": null,
"isRange": false,
"format": "HH:mm:ss",
"valueFormat": "HH:mm:ss",
"placeholder": "选择时间",
"disabled": false,
"clearable": true,
"size": "default"
},
"formItem": {
"label": "会议时间",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value) {
callback(new Error("请选择时间"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择时间",
"trigger": "change"
}
],
"config": {}
}
colorPicker(颜色选择器)
用于选择颜色值。
🔸type
固定值:"colorPicker"(颜色选择器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的颜色值 | string | "" |
| disabled | 是否禁用 | boolean | false |
| showAlpha | 是否显示透明度选择 | boolean | false |
| size | 组件尺寸 | string | "default" |
{
"type": "colorPicker",
"name": "themeColor",
"control": {
"modelValue": "#409EFF",
"disabled": false,
"showAlpha": false,
"size": "default"
},
"formItem": {
"label": "主题颜色",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value) {
callback(new Error("请选择颜色"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择颜色",
"trigger": "change"
}
],
"config": {}
}
switch(开关)
用于切换开/关状态。
🔸type
固定值:"switch"(开关组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的开关状态 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| activeText | 开启时显示文字 | string | "" |
| inactiveText | 关闭时显示文字 | string | "" |
| activeColor | 开启时颜色 | string | "#409EFF" |
| inactiveColor | 关闭时颜色 | string | "#C0CCDA" |
{
"type": "switch",
"name": "isActive",
"control": {
"modelValue": true,
"disabled": false,
"activeText": "开",
"inactiveText": "关",
"activeColor": "#409EFF",
"inactiveColor": "#C0CCDA"
},
"formItem": {
"label": "是否激活",
"rules": [
{
"validator": (rule, value, callback) => {
callback();
},
"trigger": "change"
}
]
},
"customRules": [],
"config": {}
}
inputNumber(数字输入框)
用于输入数字,可以设置范围、步进等。
🔸type
固定值:"inputNumber"(数字输入框组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的数值 | number | 0 |
| min | 最小值 | number | — |
| max | 最大值 | number | — |
| step | 步进值 | number | 1 |
| disabled | 是否禁用 | boolean | false |
| size | 组件尺寸 | string | "default" |
{
"type": "inputNumber",
"name": "age",
"control": {
"modelValue": 18,
"min": 0,
"max": 120,
"step": 1,
"disabled": false,
"size": "default"
},
"formItem": {
"label": "年龄",
"rules": [
{
"validator": (rule, value, callback) => {
if (value === null || value === undefined) {
callback(new Error("请输入年龄"));
} else if (value < 0 || value > 120) {
callback(new Error("年龄范围为 0-120"));
} else {
callback();
}
},
"trigger": "blur"
}
]
},
"customRules": [
{
"type": "number",
"min": 0,
"max": 120,
"message": "年龄范围为 0-120",
"trigger": "blur"
}
],
"config": {}
}
cascader(级联选择器)
用于选择多级分类数据。
🔸type
固定值:"cascader"(级联选择器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的选中值数组 | array | [] |
| options | 级联选项数据 | Array<{label, value, children}> | [] |
| disabled | 是否禁用 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| placeholder | 占位提示文字 | string | "" |
| size | 组件尺寸 | string | "default" |
{
"type": "cascader",
"name": "address",
"control": {
"modelValue": [],
"options": [
{
"label": "浙江",
"value": "zj",
"children": [
{ "label": "杭州", "value": "hz" },
{ "label": "宁波", "value": "nb" }
]
},
{
"label": "江苏",
"value": "js",
"children": [
{ "label": "南京", "value": "nj" },
{ "label": "苏州", "value": "sz" }
]
}
],
"disabled": false,
"clearable": true,
"placeholder": "请选择地址",
"size": "default"
},
"formItem": {
"label": "地址",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value || value.length === 0) {
callback(new Error("请选择地址"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择地址",
"trigger": "change"
}
],
"config": {}
}
rate(评分)
用于评分选择,通常显示星星。
🔸type
固定值:"rate"(评分组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 当前评分 | number | 0 |
| max | 最大分数 | number | 5 |
| disabled | 是否禁用 | boolean | false |
| allowHalf | 是否允许半星评分 | boolean | false |
| showText | 是否显示文本说明 | boolean | false |
| showScore | 是否显示数字评分 | boolean | false |
| size | 组件尺寸 | string | "default" |
{
"type": "rate",
"name": "score",
"control": {
"modelValue": 3,
"max": 5,
"disabled": false,
"allowHalf": true,
"showText": false,
"showScore": false,
"size": "default"
},
"formItem": {
"label": "评分",
"rules": [
{
"validator": (rule, value, callback) => {
if (value === null || value === undefined || value === 0) {
callback(new Error("请评分"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请评分",
"trigger": "change"
}
],
"config": {}
}
slider(滑动条)
用于选择数值范围或单个数值。
🔸type
固定值:"slider"(滑动条组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 当前数值(范围模式为数组) | number | array | 0 |
| min | 最小值 | number | 0 |
| max | 最大值 | number | 100 |
| step | 步长 | number | 1 |
| disabled | 是否禁用 | boolean | false |
| range | 是否范围选择 | boolean | false |
| showTooltip | 是否显示提示 | boolean | true |
| size | 组件尺寸 | string | "default" |
{
"type": "slider",
"name": "volume",
"control": {
"modelValue": 50,
"min": 0,
"max": 100,
"step": 1,
"disabled": false,
"range": false,
"showTooltip": true,
"size": "default"
},
"formItem": {
"label": "音量",
"rules": [
{
"validator": (rule, value, callback) => {
if (value === null || value === undefined) {
callback(new Error("请选择音量"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [],
"config": {}
}
treeSelect(树形选择器)
用于选择树形结构中的某个或多个节点。
🔸type
固定值:"treeSelect"(树形选择器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 绑定的值(多选时为数组) | array | string | [] |
| treeData | 树形数据 | Array<{label, id, children}> | [] |
| multiple | 是否多选 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| clearable | 是否显示清除按钮 | boolean | false |
| placeholder | 占位提示文字 | string | "" |
| size | 组件尺寸 | string | "default" |
{
"type": "treeSelect",
"name": "category",
"control": {
"modelValue": [],
"treeData": [
{
"label": "电子产品",
"id": 1,
"children": [
{ "label": "手机", "id": 2 },
{ "label": "电脑", "id": 3 }
]
}
],
"multiple": true,
"disabled": false,
"clearable": true,
"placeholder": "请选择类别",
"size": "default"
},
"formItem": {
"label": "类别",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value || (Array.isArray(value) && value.length === 0)) {
callback(new Error("请选择类别"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请选择类别",
"trigger": "change"
}
],
"config": {}
}
txt(文本显示)
用于显示只读文本。
🔸type
固定值:"txt"(文本显示组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 显示的文本内容 | string | "" |
{
"type": "txt",
"name": "descriptionText",
"control": {
"modelValue": "这是只读文本"
},
"formItem": {
"label": "说明",
"rules": []
},
"customRules": [],
"config": {}
}
title(标题)
用于显示标题文本。
🔸type
固定值:"title"(标题组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 标题文本内容 | string | "" |
{
"type": "title",
"name": "pageTitle",
"control": {
"modelValue": "用户管理"
},
"formItem": {},
"customRules": [],
"config": {}
}
tabs(标签页)
用于创建标签页切换。
🔸type
固定值:"tabs"(标签页组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 当前激活的标签名 | string | "" |
| tabs | 标签数组 | Array<{label, name}> | [] |
{
"type": "tabs",
"name": "mainTabs",
"control": {
"modelValue": "tab1",
"tabs": [
{ "label": "标签1", "name": "tab1" },
{ "label": "标签2", "name": "tab2" }
]
},
"formItem": {},
"customRules": [],
"config": {}
}
flex(弹性布局)
用于布局弹性容器。
🔸type
固定值:"flex"(弹性布局组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| justify | 主轴对齐方式 | string | "start" |
| align | 侧轴对齐方式 | string | "stretch" |
| direction | 主轴方向 | string | "row" |
| wrap | 是否换行 | string | "nowrap" |
{
"type": "flex",
"name": "flexContainer",
"control": {
"justify": "start",
"align": "center",
"direction": "row",
"wrap": "nowrap"
},
"formItem": {},
"customRules": [],
"config": {}
}
card(卡片)
用于显示卡片容器。
🔸type
固定值:"card"(卡片组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| header | 卡片头部标题 | string | "" |
| bordered | 是否有边框 | boolean | false |
| shadow | 是否有阴影 | boolean | false |
{
"type": "card",
"name": "userCard",
"control": {
"header": "用户信息",
"bordered": true,
"shadow": true
},
"formItem": {},
"customRules": [],
"config": {}
}
divider(分割线)
用于分隔内容。
🔸type
固定值:"divider"(分割线组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| direction | 分割线方向 | string | "horizontal" |
| contentPosition | 内容位置 | string | "center" |
{
"type": "divider",
"name": "lineDivider",
"control": {
"direction": "horizontal",
"contentPosition": "center"
},
"formItem": {},
"customRules": [],
"config": {}
}
button(按钮)
用于触发操作。
🔸type
固定值:"button"(按钮组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| text | 按钮显示文本 | string | "" |
| type | 按钮类型 | string | "default" |
| size | 按钮尺寸 | string | "default" |
| disabled | 是否禁用 | boolean | false |
| loading | 是否加载中 | boolean | false |
| icon | 按钮图标名称 | string | "" |
{
"type": "button",
"name": "submitBtn",
"control": {
"text": "提交",
"type": "primary",
"size": "default",
"disabled": false,
"loading": false,
"icon": "Check"
},
"formItem": {},
"customRules": [],
"config": {}
}
table(表格)
用于显示表格数据。
🔸type
固定值:"table"(表格组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| columns | 表格列配置 | Array<{label, prop}> | [] |
| data | 表格数据 | Array<object> | [] |
{
"type": "table",
"name": "userTable",
"control": {
"columns": [
{ "label": "姓名", "prop": "name" },
{ "label": "年龄", "prop": "age" }
],
"data": []
},
"formItem": {},
"customRules": [],
"config": {}
}
component(自定义组件)
用于嵌入自定义组件。
🔸type
固定值:"component"(自定义组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| componentName | 自定义组件名称 | string | "" |
| props | 传递给自定义组件的属性 | object | {} |
{
"type": "component",
"name": "customComp",
"control": {
"componentName": "MyComponent",
"props": {}
},
"formItem": {},
"customRules": [],
"config": {}
}
upload(上传)
用于文件上传。
🔸type
固定值:"upload"(上传组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| action | 上传接口地址 | string | "" |
| multiple | 是否支持多文件上传 | boolean | false |
| accept | 接受的文件类型 | string | "" |
| fileList | 已上传文件列表 | array | [] |
| disabled | 是否禁用 | boolean | false |
| showFileList | 是否显示文件列表 | boolean | true |
{
"type": "upload",
"name": "avatar",
"control": {
"action": "/upload",
"multiple": false,
"accept": "image/*",
"fileList": [],
"disabled": false,
"showFileList": true
},
"formItem": {
"label": "头像上传",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value || (Array.isArray(value) && value.length === 0)) {
callback(new Error("请上传文件"));
} else {
callback();
}
},
"trigger": "change"
}
]
},
"customRules": [
{
"required": true,
"message": "请上传文件",
"trigger": "change"
}
],
"config": {}
}
tinymce(富文本编辑器)
用于编辑富文本内容。
🔸type
固定值:"tinymce"(富文本编辑器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| modelValue | 富文本内容 | string | "" |
| disabled | 是否禁用编辑 | boolean | false |
| height | 编辑器高度(像素) | number | 300 |
{
"type": "tinymce",
"name": "content",
"control": {
"modelValue": "",
"disabled": false,
"height": 300
},
"formItem": {
"label": "内容",
"rules": [
{
"validator": (rule, value, callback) => {
if (!value) {
callback(new Error("请输入内容"));
} else {
callback();
}
},
"trigger": "blur"
}
]
},
"customRules": [
{
"required": true,
"message": "请输入内容",
"trigger": "blur"
}
],
"config": {}
}
grid(网格布局)
用于布局网格容器。
🔸type
固定值:"grid"(网格布局组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| cols | 列数 | number | 24 |
| gutter | 栅格间距 | number | 0 |
| justify | 主轴对齐方式 | string | "start" |
| align | 侧轴对齐方式 | string | "top" |
{
"type": "grid",
"name": "gridLayout",
"control": {
"cols": 4,
"gutter": 10,
"justify": "start",
"align": "top"
},
"formItem": {},
"customRules": [],
"config": {}
}
div(容器)
用于包裹内容的容器。
🔸type
固定值:"div"(容器组件)
🔸control 对象属性说明
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| style | 容器自定义样式 | object | {} |
{
"type": "div",
"name": "contentWrapper",
"control": {
"style": {
"padding": "10px",
"backgroundColor": "#f5f5f5"
}
},
"formItem": {},
"customRules": [],
"config": {}
}
name 字段名
说明:绑定数据的字段名,在同一表单中必须唯一
| 项目 | 内容 |
|---|---|
| 类型 | string |
| 必填 | 是 |
| 默认值 | — |
| 示例 | "username" |
control 组件属性配置
| 属性名 | 说明 | 类型 | 是否必填 | 默认值 | 示例值 |
|---|---|---|---|---|---|
| modelValue | 绑定的输入值,通常双向绑定 | string | number | 否 | "" | "" |
| type | 输入框类型,如 text、password | string | 否 | "text" | "text" |
| placeholder | 输入框占位提示文字 | string | 否 | "" | "请输入用户名" |
| maxlength | 最大输入长度 | number | 否 | — | 20 |
| minlength | 最小输入长度 | number | 否 | — | 3 |
| showWordLimit | 是否显示字数统计 | boolean | 否 | false | true |
| clearable | 是否显示清除按钮 | boolean | 否 | false | true |
| disabled | 是否禁用输入框 | boolean | 否 | false | false |
| readonly | 是否只读 | boolean | 否 | false | false |
| autocomplete | 浏览器自动完成功能 | string | 否 | "off" | "off" |
| autofocus | 是否自动聚焦 | boolean | 否 | false | false |
| tabindex | tab 键顺序 | string | number | 否 | — | "1" |
| validateEvent | 是否触发表单验证事件 | boolean | 否 | true | true |
| inputStyle | 输入框自定义样式对象 | object | 否 | {} | { color: "#333", fontSize: "14px" } |
| size | 输入框尺寸,支持 small/default/large | string | 否 | "default" | "default" |
| options | 选项数组(常用于 select、radio 等) | Array<{ label: string; value: any }> | 否 | [] | [ { label: "选项1", value: "1" }, { label: "选项2", value: "2" } ] |
| multiple | 是否多选 | boolean | 否 | false | false |
| filterable | 是否支持搜索筛选 | boolean | 否 | false | true |
| rows | 多行文本框行数,textarea 专用 | number | 否 | 2 | 4 |
| resize | textarea 是否允许调整大小及方向 | string | 否 | "none" | "vertical" |
| autosize | textarea 自动高度配置 | object | 否 | null | { minRows: 2, maxRows: 6 } |
| buttonStyle | radio 按钮样式 | string | 否 | "outline" | "outline" |
| min | 数字类组件最小值 | number | 否 | 0 | 0 |
| max | 数字类组件最大值 | number | 否 | 100 | 100 |
| step | 数字类组件步长 | number | 否 | 1 | 1 |
| format | 日期格式,datePicker 专用 | string | 否 | "" | "yyyy-MM-dd" |
| placeholderTime | 时间选择器占位提示 | string | 否 | "" | "选择时间" |
| disabledDate | 禁用日期函数 | function | 否 | null | (date) => date < new Date() |
| showAlpha | 颜色选择器是否显示透明度 | boolean | 否 | false | false |
| activeColor | 颜色选择器主题色 | string | 否 | "#409EFF" | "#409EFF" |
| checked | 开关状态,switch 组件专用 | boolean | 否 | false | false |
| icon | 按钮图标名 | string | 否 | "" | "Check" |
| loading | 按钮加载状态 | boolean | 否 | false | false |
| text | 按钮文本 | string | 否 | "" | "提交" |
| columns | 表格列配置 | Array<{ label: string; prop: string }> | 否 | [] | [ { label: "姓名", prop: "name" }, { label: "年龄", prop: "age" } ] |
| data | 表格数据 | Array | 否 | [] | [] |
| style | 容器样式 | object | 否 | {} | { padding: "10px", backgroundColor: "#f5f5f5" } |
| height | 富文本编辑器高度 | number | 否 | 300 | 300 |
| action | 上传接口地址 | string | 否 | "" | "/upload" |
| multipleUpload | 是否支持多文件上传 | boolean | 否 | false | false |
| showFileList | 是否显示文件列表 | boolean | 否 | true | true |
formItem 表单项配置
| 属性名 | 说明 | 类型 | 是否必填 | 默认值 | 示例值 |
|---|---|---|---|---|---|
| label | 表单标签文字 | string | 否 | "" | "确认密码" |
| rules | 校验规则数组 | Array | 否 | 见自定义验证函数示例 |
校验示例
opt = {
list: [
{
type: "password",
name: "userPassword",
control:
{
modelValue: ""
},
config:
{},
formItem:
{
label: "密码",
rules: [
{
required: true,
message: "请输入密码",
trigger: "blur"
},
{
min: 6,
message: "密码长度不能少于6位",
trigger: "blur"
}]
}
},
{
type: "password",
name: "confirmPassword",
control:
{
modelValue: ""
},
config:
{},
formItem:
{
label: "确认密码",
rules: [
{
required: true,
message: "请再次输入密码",
trigger: "blur"
},
{
validator: (rule, value, callback) =>
{
// 👉 注意这里也要改
const password = getTestDemoValueByName("userPassword");
if (!value)
{
callback(new Error("请再次输入密码"));
}
else if (value !== password)
{
callback(new Error("两次密码输入不一致"));
}
else
{
callback();
}
},
trigger: "blur"
}]
}
}],
form:
{
size: "default",
labelWidth: "100px",
name: "TestDemo"
},
config:
{
submitCancel: true
}
}
customRules 自定义校验规则
| 属性名 | 说明 | 类型 | 是否必填 | 默认值 | 示例值 |
|---|---|---|---|---|---|
| type | 规则类型 | string | 是 | — | "required" |
| message | 规则提示信息 | string | 是 | — | "必填项" |
| trigger | 触发校验时机 | string | 是 | — | "blur" |
opt = {
list: [
{
type: "input",
control:
{
modelValue: "2@qq.com"
},
config:
{},
name: "inputEmail",
formItem:
{
label: "邮箱地址"
},
customRules: [
{
type: "required",
message: "必填项",
trigger: "blur"
},
{
type: "email",
message: "请输入邮箱地址",
trigger: "blur"
}]
},
],
form:
{
size: "default"
},
config:
{
submitCancel: true
},
events:
{
}
}
config 扩展配置
| 属性名 | 说明 | 类型 | 是否必填 | 默认值 | 示例值 |
|---|---|---|---|---|---|
| optionsType | 自定义配置项类型 | number | 否 | — | 1 |
| optionsFun | 远程接口或本地方法名 | string | 否 | — | "demo/options" |
| method | 请求方法 | string | 否 | — | "get" |
| linkage | 关联其他组件字段名 | string | 否 | — | "name1" |
| before | 请求前钩子函数,修改请求参数 | function | 否 | — | (params, { type, route, model }) => { return params; } |
| after | 请求后钩子函数,处理响应数据 | function | 否 | — | (res, success, type) => { return res; } |
表单配置 (form)
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| name | 表单标识,可根据此标识使用 get[formName]ControlByName 获取其他选项数据 | string | — |
| labelWidth | 表单标签宽度,如 "100px" | string | — |
| class | 表单样式名称,可快速选择内置好的表单布局类名,或自定义类名 | string | — |
| showColon | 统一设置表单 label 是否添加冒号 | boolean | false |
| size | 组件尺寸 | "default" | "small" | "large" | "default" |
form: {
name: "testForm", // 表单标识
labelWidth: "100px", // 表单标签宽度
class: "custom-form", // 表单样式名称
showColon: true, // 字段名后添加冒号
size: "default" // 组件尺寸
}
补充说明:
form.name:表单的唯一标识,可用于通过get[formName]ControlByName方法获取表单中其他控件的值form.labelWidth:统一设置所有表单项标签的宽度,支持px、%等单位form.class:支持传入内置类名或自定义 CSS 类名,用于快速调整表单布局样式form.showColon:全局控制表单标签后是否显示冒号,优先级低于formItem级别的配置form.size:统一设置表单内所有组件的尺寸,可被单个组件的size属性覆盖
事件 (events)
用于控制表单在 联动、校验、提交、请求生命周期 中的行为。
| 事件名 | 作用 | 是否必须 return |
|---|---|---|
| change | 表单联动 | ❌ 可选 |
| validate | 校验提示 | ❌ 不需要 |
| format | 提交数据处理 | ✅ 必须 |
| before | 请求前拦截 | ✅ 必须 |
| after | 响应统一处理 | ✅ 必须 |
change- 用于字段变化联动
- 支持 直接修改 context.model 或
return 新对象
validate- 表单校验结果回调
- 一般用于 统一错误提示
format- 提交前对数据进行格式化
- 必须返回最终提交数据(对象 / 数组)
before- 请求发送前拦截
- 用于修改 headers / data / 参数
after- 请求完成后统一处理响应
- 用于 格式标准化(code / data / msg)
change(instance)
instance{Object}name{string} 当前变化字段名(唯一标识)value{any} 当前字段值prop{string} 字段标识(子表 / flex 时等同 name)options{Object} 当前组件配置(schema)env{Object} 运行环境(ElMessage / request 等)context{Object} 表单上下文context.model{Object} 当前表单数据(核心)context.props{Object} 组件参数
- 返回
{Object | void}
字段变化时触发,用于 联动、赋值、副作用(请求 / 提示 / UI控制)
💡 使用规则
- 简单修改 →
context.model.xxx = value - 复杂联动 →
return newModel - ❌ 不建议混用(会产生数据覆盖问题)
⚠️ 注意
- 不 return 时:
- 不触发系统更新
- 但修改
context.model仍然生效
- return 时:
- 会 整体覆盖 model
- 适用于多字段联动
change: (instance) => {
const {
name,
value,
env,
context
} = instance;
console.groupCollapsed("🔄 [change] " + name);
console.log("instance:", instance);
console.groupEnd();
// 示例1:仅监听
if (name === "xxx") {
env?.runtime?.ElMessage?.info("字段变化(仅监听)");
}
// 示例2:修改字段(推荐)
if (name === "xxx") {
context.model.otherField = value;
}
// 示例3:复杂联动
if (name === "xxx") {
const newModel = {
...context.model,
// otherField: value
};
return newModel;
}
// 示例4:副作用
if (name === "xxx") {
// await env.runtime.request(...)
}
}
validate(instance)
instance{Object}valid{boolean} 是否通过校验fields{Object} 校验失败字段集合env{Object} 运行环境context{Object} 表单上下文
- 返回
{void}
表单校验完成后触发。
💡 常见用途
- 提取第一条错误提示
- 自定义错误展示方式
- 统一提示风格
⚠️ 注意
fields结构为:{ fieldName: [ { message: "错误信息" } ] }
validate: (instance) => {
const {
valid,
fields,
env
} = instance;
console.warn("【validate】执行", instance);
const showError = (fields, defaultMsg = "表单校验失败") => {
try {
const errorList = Object.values(fields || {});
const msg = errorList?.[0]?.[0]?.message;
env.runtime.ElMessage.error(msg || defaultMsg);
} catch (e) {
env.runtime.ElMessage.error(defaultMsg);
}
};
if (!valid) {
showError(fields);
}
}
format(instance)
instance{Object}fields{Object} 表单原始数据(提交源)env{Object} 运行环境env.user用户信息env.runtime工具方法
context{Object}context.model完整表单数据
- 返回
{Object | Array}
提交前数据处理(核心步骤)
💡 能做什么
- 字段过滤(删除无用字段)
- 字段映射(重命名)
- 数据结构转换(数组 / 字符串)
- 批量数据生成
- 注入公共参数(user_id / 时间等)
⚠️ 注意
- 必须
return fields才是提交数据源(不是 model)
format: (instance) => {
const {
fields,
env,
context
} = instance;
console.groupCollapsed("🎨 [format]");
console.log("fields:", fields);
console.log("context:", context);
console.groupEnd();
return fields;
}
before(instance)
instance{Object}type{string} 请求类型get获取数据add新增edit编辑
headers{Object} 请求头(可修改)data{Object} 请求体(可修改)env{Object}context{Object}
- 返回
{Object}(axios config)
请求发送前拦截(统一入口)
💡 能做什么
- 注入 token
- 修改请求参数
- 加密 / 签名
- 统一 loading / 提示
- 按 type 分支处理
⚠️ 注意
- 必须 return 完整请求配置
- 不 return → 请求不会发送
before: (instance) => {
const {
type,
headers,
data,
env
} = instance;
console.groupCollapsed("🚀 [before] " + type);
console.log("instance:", instance);
console.groupEnd();
const newHeaders = {
...headers,
Authorization: "Bearer " + (env?.user?.token || ""),
"Content-Type": "application/json"
};
let newData = { ...data };
switch (type) {
case "get":
env?.runtime?.ElMessage?.info("加载数据");
break;
case "add":
env?.runtime?.ElMessage?.info("新增提交");
break;
case "edit":
env?.runtime?.ElMessage?.info("编辑提交");
break;
}
return {
url: instance.url,
method: instance.method || "post",
headers: newHeaders,
timeout: instance.timeout || 30000,
data: newData
};
}
after(instance)
instance{Object}response{Object} 接口返回type{string}success{boolean}env{Object}context{Object}
- 返回
{Object}标准结构
请求完成后处理返回数据(统一结构)。
{
code: number,
data: any,
msg: string
}
after: (instance) => {
const {
type,
success,
response,
env
} = instance;
console.groupCollapsed("📦 [after] " + type);
console.log("instance:", instance);
console.groupEnd();
if (success) {
switch (type) {
case "get":
env?.runtime?.ElMessage?.info("get 处理");
break;
case "add":
env?.runtime?.ElMessage?.info("add 处理");
break;
case "edit":
env?.runtime?.ElMessage?.info("edit 处理");
break;
}
}
return {
code: 200,
data: response?.data?.data,
msg: response?.data?.msg
};
}
接口行为配置 (config)
config: {
submitCancel: boolean, // 是否显示提交/取消
addUrl: string, // 新增接口
editUrl: string, // 编辑接口
getUrl: string // 查看详情接口
}
⚠️ 注意:
接口请求可能会涉及跨域问题。例如:当前页面运行在云控官网后台域名(如 http://cloud.jsdevhub.com),而接口地址是 http://47.94.105.29:66,会因浏览器同源策略被拦截。解决方式建议:后端开启 CORS 并允许跨域
选项数据格式要求
适用于 select / selectPlus 等组件:
[
{ "id": 1, "label": "选项 A" },
{ "id": 2, "label": "选项 B" }
]
需要配合:optionsType: 1、optionsFun、value、label 等字段使用。
完整配置示例
opt = {
list: [
{
type: "input",
control:
{
modelValue: "",
placeholder: "请输入标题"
},
config:
{},
name: "label",
formItem:
{
label: "标题"
}
},
{
type: "selectPlus",
control:
{
modelValue: "",
appendToBody: true,
valueKey: "id",
filterable: true,
props:
{
label: "label",
value: "id"
}
},
options: [],
config:
{
optionsType: 1,
optionsFun: "http://47.94.105.29:66/api/DataListCaseCategoryList",
method: "post",
addUrl: "http://47.94.105.29:66/api/addDataListCaseCategory",
editUrl: "http://47.94.105.29:66/api/editDataListCaseCategory",
deleteUrl: "http://47.94.105.29:66/api/deleteDataListCaseCategory"
},
name: "category_id",
formItem:
{
label: "分类"
}
},
{
type: "input",
control:
{
modelValue: "",
placeholder: "请输入链接"
},
config:
{},
name: "link",
formItem:
{
label: "链接"
}
},
{
type: "input",
control:
{
modelValue: "",
placeholder: "请输入uid"
},
config:
{},
name: "uid",
formItem:
{
label: "UID"
}
},
{
type: "select",
control:
{
modelValue: "",
appendToBody: true,
placeholder: "请选择任务类型"
},
options: [],
config:
{
optionsType: 1,
optionsFun: "http://47.94.105.29:66/api/getFieldTaskTypeIdDict",
method: "post"
},
name: "task_type_id",
formItem:
{
label: "任务类型"
},
events:
{
after: (instance) =>
{
const
{
type,
success,
response,
env,
context
} = instance;
// ================= 调试日志 =================
console.groupCollapsed("📦 [after] " + type);
console.log("instance:", instance);
console.groupEnd();
return {
code: 200,
data: response?.data?.data?.list,
msg: response?.data?.msg
};
}
}
},
{
type: "select",
control:
{
modelValue: "",
appendToBody: true
},
options: [],
config:
{
optionsType: 1,
optionsFun: "http://180.76.145.80/api/getDeviceList",
method: "post",
value: "id"
},
name: "device_id",
formItem:
{
label: "设备"
}
},
{
type: "select",
control:
{
modelValue: "",
appendToBody: true
},
options: [],
config:
{
optionsType: 1,
optionsFun: "http://180.76.145.80/api/getUserList",
method: "post",
value: "id"
},
name: "user_id",
formItem:
{
label: "用户"
}
},
{
type: "upload",
control:
{
modelValue: "",
action: "http://47.94.105.29:66/api/upload",
multiple: true,
limit: 2,
listType: "picture-card"
},
config:
{
tip: "",
btnText: ""
},
name: "upload",
formItem:
{
label: "图片文件上传"
}
},
{
type: "datePicker",
control:
{
modelValue: "",
type: "datetime"
},
config:
{},
name: "datePicker",
formItem:
{
label: "日期选择器"
}
},
{
type: "timePicker",
control:
{
modelValue: ""
},
config:
{},
name: "timePicker",
formItem:
{
label: "时间选择器",
rules: [
{
required: true,
message: "请选择结束时间",
trigger: "change"
},
{
validator: (rule, value, callback) =>
{
const val = getTestDemoValueByName('datePicker')
if (value <= val)
{
callback(new Error('结束时间必须大于开始时间'))
}
else
{
callback()
}
},
trigger: "blur"
}]
}
},
{
type: "colorPicker",
control:
{
modelValue: ""
},
config:
{},
name: "colorPicker",
formItem:
{
label: "取色器"
}
},
{
type: "rate",
control:
{
modelValue: 0
},
config:
{},
name: "rate",
formItem:
{
label: "评分"
}
},
{
type: "slider",
control:
{
modelValue: 0
},
config:
{},
name: "slider",
formItem:
{
label: "滑块"
}
},
{
type: "inputNumber",
control:
{
modelValue: 0
},
config:
{},
name: "inputNumber",
formItem:
{
label: "计数器"
}
},
{
type: "button",
control:
{
label: "AI 内容生成",
style:
{
"margin-left": "100px",
"margin-bottom": "10px"
},
key: "none",
type: "info"
},
config:
{
source: 497,
openType: "drawer",
width: "100%"
},
events:
{
submit: (instance) =>
{
console.warn("📌 submit来源组件 / 行为:", instance);
const
{
selected,
model,
env,
context
} = instance;
var aiList = selected.articleTable || [];
var aiText = "";
if (Array.isArray(aiList) && aiList.length > 0)
{
aiText = aiList
.filter(function(item)
{
return item && item.content;
})
.map(function(item)
{
return String(item.content);
})
.join("\n\n"); // 👈 关键:双换行
}
var oldText = model.textarea || "";
// ❗ 不要 trim(重点)
if (oldText && oldText.trim() !== "")
{
context.model.textarea = oldText + "\n\n" + aiText;
}
else
{
context.model.textarea = aiText;
}
// api.ElMessage({
// message: "回填成功",
// type: "success"
// });
},
cancel: (instance) =>
{
console.log("取消了");
console.log("🚀 [cancel instance]:", instance);
}
}
},
{
type: "textarea",
control:
{
modelValue: "",
placeholder: "请输入多行文本,或者使用上方按钮通过AI快捷输入",
autosize:
{
minRows: 5,
maxRows: 8
}
},
config:
{},
name: "textarea",
formItem:
{
label: "多行文本"
}
},
{
type: "switch",
control:
{
modelValue: false,
activeValue: 1,
inactiveValue: 0
},
config:
{},
name: "switch",
formItem:
{
label: "开关"
}
},
{
type: "upload",
control:
{
modelValue: "",
action: "http://47.94.105.29:66/api/upload"
},
config:
{},
name: "play",
formItem:
{
label: "播放"
}
},
{
type: "upload",
control:
{
modelValue: "",
action: "http://47.94.105.29:66/api/upload"
},
config:
{},
name: "download",
formItem:
{
label: "下载链接"
}
},
{
type: "upload",
control:
{
modelValue: "",
action: "http://47.94.105.29:66/api/upload",
multiple: true,
limit: 2,
listType: "picture-card"
},
config:
{},
name: "image",
formItem:
{
label: "图片/文件"
}
},
{
type: "upload",
control:
{
modelValue: "",
action: "http://47.94.105.29:66/api/upload",
limit: 1,
drag: true
},
config:
{},
name: "video",
formItem:
{
label: "视频文件"
}
},
{
type: "input",
control:
{
modelValue: ""
},
config:
{},
name: "copy",
formItem:
{
label: "复制文本"
}
}],
form:
{
size: "default",
labelWidth: "100px",
name: "TestDemo"
},
events:
{
validate: (instance) =>
{
/**
* ===============================
* 📌 表单校验结果回调
* ===============================
*
* valid -> 是否通过校验(true / false)
* fields -> 校验失败字段集合(用于获取错误信息)
* env -> 运行环境(可调用 ElMessage 等能力)
* context -> 当前表单上下文数据
*/
const
{
valid,
fields,
env,
context
} = instance;
console.warn("【validate】执行", instance);
/**
* 📌 安全提取错误提示(只取第一条)
*/
const showError = (fields, defaultMsg = "表单校验失败") =>
{
try
{
if (!fields || typeof fields !== "object")
{
env.runtime.ElMessage.error(defaultMsg);
return;
}
const errorList = Object.values(fields);
if (!errorList.length)
{
env.runtime.ElMessage.error(defaultMsg);
return;
}
const firstItem = errorList[0];
if (!Array.isArray(firstItem) || !firstItem.length)
{
env.runtime.ElMessage.error(defaultMsg);
return;
}
const msg = firstItem[0]?.message;
env.runtime.ElMessage.error(msg || defaultMsg);
}
catch (e)
{
env.runtime.ElMessage.error(defaultMsg);
}
};
// ❌ 校验失败 → 自动提示
if (!valid)
{
showError(fields);
}
},
before: (instance) =>
{
/**
* =========================================================
* 🔧 before:请求发送前处理钩子(核心能力)
* =========================================================
*
* 👉 作用:
* - 统一修改请求参数(headers / data / config)
* - 注入 token / 鉴权信息
* - 请求预处理(日志 / 过滤 / 加密等)
*
*
* =========================================================
* 📦 instance:请求上下文
* =========================================================
* headers -> 请求头(可修改)
* data -> 请求体数据(可修改)
* type -> 请求类型(get / add / edit)
* env -> 运行环境(工具集合)
* context -> 表单页上下文(运行时数据)
*
* =========================================================
* 🧭 type:请求类型
* =========================================================
*
* get - 获取表单数据
* add - 新增表单数据
* edit - 编辑表单数据
*
* 💡 说明:
* - type 用于区分不同数据来源与操作行为
* - 可在 before / after 中做分支处理
*
* =========================================================
* 🌍 env:运行环境能力
* =========================================================
*
* env.runtime:
* - request
* - ElMessage
* - ElNotification
* - ElMessageBox
*
* env.user:
* - id
* - uname
* - token
*
* env.router:
* - 路由实例
*
* =========================================================
* 🌍 context:表单页上下文(运行时数据)
* =========================================================
*
* 👉 说明:
* context 表示当前表单页面的“运行时状态”,
* 可用于获取或修改表单数据
*
*
* ---------------------------------------------------------
* 📄 context.model:表单数据模型(核心)
* ---------------------------------------------------------
* - 当前表单的所有字段数据
* - 类型:object
*
*
* =========================================================
* 💡 默认行为说明
* =========================================================
* before 负责“修改请求”
* after 负责“处理响应”
*/
const
{
type,
headers,
data,
env,
context
} = instance;
// ================= 调试日志 =================
console.groupCollapsed("🚀 [before] " + type);
console.log("instance:", instance);
console.groupEnd();
// ================= 请求头重构 =================
const newHeaders = {
...headers,
Authorization: "Bearer " + (env?.user?.token || ""),
"Content-Type": "application/json"
};
// ================= 请求数据处理 =================
let newData = {
};
// ================= 请求前处理(按 type 分发) =================
switch (type)
{
case "get":
{
env?.runtime?.ElMessage?.info(
"正在加载表单数据(可在此处处理字段映射 / 默认值)"
);
newData = {
...data
};
break;
}
case "add":
{
env?.runtime?.ElMessage?.info(
"正在提交新增表单(可在此处处理提交参数格式)"
);
newData = {
...data
};
break;
}
case "edit":
{
env?.runtime?.ElMessage?.info(
"正在提交编辑表单(可在此处处理提交参数格式)"
);
newData = {
...data
};
break;
}
default:
{
newData = {
...data
};
break;
}
}
// ================= 返回 axios 配置 =================
return {
url: instance.url,
method: instance.method || "post",
headers: newHeaders,
timeout: instance.timeout || 30000,
data: newData
};
},
after: (instance) =>
{
/**
* =========================================================
* 🔧 after:请求结果后处理钩子(核心能力)
* =========================================================
*
* 👉 作用:
* - 统一接口返回结构(核心)
* - 提供默认行为(如提示)
* - 支持用户自定义扩展逻辑
*
*
* =========================================================
* 📦 instance:请求上下文(after 阶段)
* =========================================================
*
* response-> 接口返回结果(axios response)
* type -> 当前操作类型(get / add / edit)
* success -> 请求是否成功(boolean)
* env -> 运行环境(工具集合)
* context -> 表单页上下文(运行时数据)
*
*
* =========================================================
* 📄 response:接口响应数据(核心)
* =========================================================
* - 原始接口返回结果(通常为 axios response)
* - 常用访问方式:
*
* response.data -> 后端返回体
*
*
* =========================================================
* 🧭 type:当前操作类型
* =========================================================
* get -> 获取表单数据(回显)
* add -> 新增提交
* edit -> 编辑提交
*
*
* =========================================================
* ✅ success:请求是否成功
* =========================================================
* true -> 请求成功(进入 after 逻辑)
* false -> 请求失败(已由底层统一处理)
*
*
* =========================================================
* 🌍 env:运行环境
* =========================================================
* env.runtime:
* - request -> 网络请求方法(axios 封装)
* - ElMessage -> 消息提示
* - ElNotification -> 通知提示
* - ElMessageBox -> 弹窗
*
* env.user:
* - id
* - uname
* - token
*
* env.router:
* - 路由实例
*
*
* =========================================================
* 🌍 context:表单页上下文(运行时数据)
* =========================================================
*
* 👉 说明:
* context 表示当前表单页面的“运行时状态”,
* 可用于获取或修改表单数据
*
*
* ---------------------------------------------------------
* 📄 context.model:表单数据模型(核心)
* ---------------------------------------------------------
* - 当前表单的所有字段数据
* - 类型:object
*
*
* =========================================================
* 💡 默认行为(可删除)
* =========================================================
* - 根据 type 自动提示
* - 仅用于演示,实际项目可自行修改或删除
*/
const
{
type,
success,
response,
env,
context
} = instance;
// ================= 调试日志 =================
console.groupCollapsed("📦 [after] " + type);
console.log("instance:", instance);
console.groupEnd();
// ================= 默认提示(演示用) =================
if (success)
{
switch (type)
{
// ================= 表单数据加载处理 =================
case "get":
{
env?.runtime?.ElMessage?.info(
"get 数据处理区:可在此处处理表单数据加载 / 字段映射 / 默认值填充"
);
break;
}
// ================= 表单数据新增处理 =================
case "add":
{
env?.runtime?.ElMessage?.info(
"add 数据处理区:可在此处处理新增提交后的返回结构 / 状态处理"
);
break;
}
// ================= 表单数据编辑处理 =================
case "edit":
{
env?.runtime?.ElMessage?.info(
"edit 数据处理区:可在此处处理编辑提交后的返回结构 / 字段同步"
);
break;
}
default:
{
env?.runtime?.ElMessage?.info(
"未知 type:" + type + ",可在此处扩展表单处理逻辑"
);
break;
}
}
}
/**
* =========================================================
* 📦 统一返回数据格式(核心规范)
* =========================================================
*
* 👉 所有请求最终都会被转换为:
*
* {
* code: number,
* data: any,
* msg: string
* }
*
*
* ---------------------------------------------------------
* 🔢 code:状态码
* ---------------------------------------------------------
* 200 -> 请求成功
* 400 -> 业务失败(如参数错误)
* 401 -> 用户异常(登录失效,自动处理)
*
* 👉 用法:
* if (response.code === 200) { ... }
*
*
* ---------------------------------------------------------
* 📄 data:业务数据
* ---------------------------------------------------------
* - 接口核心数据
* - 类型:对象 或 数组
*
* 💡 示例:
* data = { id: 1, name: "张三" }
* data = [ { id: 1, name: "张三" }, { id: 2, name: "李四" } ]
*
*
* ---------------------------------------------------------
* 💬 msg:提示信息
* ---------------------------------------------------------
* - 用于 UI 提示
* - 一般来自后端
*
* 👉 用法:
* env.runtime.ElMessage.success(msg)
*
*
* =========================================================
* 💡 扩展说明(重要)
* =========================================================
* 不同后端接口返回结构可能不一致,
* 你需要在 after 中将数据“统一规范化”为标准格式:
*
* 👉 标准格式:
* {
* code: number,
* data: object,
* msg: string
* }
*
*
* =========================================================
* 📌 示例1:字段结构不一致(基础映射)
* =========================================================
*
* 后端返回:
* {
* code: 0,
* result: {...},
* message: "success"
* }
*
* 👉 转换:
* return {
* code: response.data.code,
* data: response.data.result,
* msg: response.data.message
* }
*
*
* =========================================================
* 📌 示例2:data 是 JSON 字符串(常见)
* =========================================================
*
* 后端返回:
* {
* code: 200,
* result: "{"id":1,"name":"张三"}",
* message: "ok"
* }
*
* 👉 转换:
* return {
* code: response.data.code,
* data: JSON.parse(response.data.result), // 字符串 → 对象
* msg: response.data.message
* }
*
*
* =========================================================
* 📌 示例3:复杂字符串解析
* =========================================================
*
* 后端返回:
* {
* code: 200,
* result: "id=1,name=张三,age=18"
* }
*
* 👉 转换:
* const obj = Object.fromEntries(
* response.data.result.split(",").map(item => item.split("="))
* );
*
* return {
* code: response.data.code,
* data: obj,
* msg: response.data.message
* }
*
*
* =========================================================
* ⚠️ 核心原则(非常重要)
* =========================================================
* 无论后端返回:
* - 对象
* - JSON字符串
* - 普通字符串
* - 拼接字符串
*
* 👉 最终都必须转换为:
* {
* code,
* data,
* msg
* }
*
* ❗否则前端无法统一处理数据结构
*/
return {
code: 200,
data: response?.data?.data,
msg: response?.data?.msg
};
},
change: (instance) =>
{
/**
* =========================================================
* 🔧 change:表单字段变化回调(核心能力)
* =========================================================
*
* 👉 作用:
* - 监听字段变化
* - 表单联动(自动填充 / 计算)
* - 执行副作用(请求 / 提示 / 控制UI)
*
*
* =========================================================
* 📦 instance:变化上下文(统一结构)
* =========================================================
*
* name -> 当前变化字段名
* value -> 当前字段值
* prop -> 字段标识(子表或flex时的prop 同 name)
* options -> 组件配置
*
* env -> 运行环境(工具集合)
* context -> 表单上下文(推荐使用)
*
*
* =========================================================
* 🌍 context(推荐使用)
* =========================================================
*
* context.model -> 当前表单数据(核心)
* context.props -> 组件参数
*
*
* =========================================================
* 💡 返回值行为规范(非常重要)
* =========================================================
*
* 👉 不 return:
* - 不触发系统自动更新
* - ✅ 可以通过 context.model 手动修改数据
*
* 👉 return object:
* - 覆盖整个 model(复杂联动)
*
* ⚠️ 注意:
* - 不建议同时使用 return + context.model
* - 避免数据冲突
*/
const
{
name,
value,
model,
prop,
options,
env,
context
} = instance;
// ================= 调试日志 =================
console.groupCollapsed("🔄 [change] " + name);
console.log("instance:", instance);
console.groupEnd();
/**
* =========================================================
* 📌 示例1:仅监听(不修改数据)
* =========================================================
*/
if (name === "xxx")
{
env?.runtime?.ElMessage?.info("字段变化(仅监听)");
// ❗ 不 return
// ❗ 不修改 context.model
}
/**
* =========================================================
* 📌 示例2:使用 context.model 修改(推荐方式2)
* =========================================================
*
* 👉 适用于:
* - 简单赋值
* - 副作用逻辑
*/
if (name === "xxx")
{
context.model.otherField = value;
// ❗ 不 return
}
/**
* =========================================================
* 📌 示例3:return object(复杂联动)
* =========================================================
*
* 👉 适用于多字段 / 条件逻辑
*/
if (name === "xxx")
{
const newModel = {
...context.model,
// otherField: value,
// anotherField: "xxx"
};
// return newModel;
}
/**
* =========================================================
* 📌 示例4:副作用(请求 / 计算)
* =========================================================
*
* 👉 不需要 return
*/
if (name === "xxx")
{
// 示例:发请求
// const response = await env.runtime.request({
// url: "【请替换为你的接口地址】/api/xxx",
// method: "post",
// data: {
// model: context.model
// }
// });
// console.log("📦 response:", response);
}
/**
* =========================================================
* 📌 默认行为(无返回)
* =========================================================
*
* 👉 不 return:
* - 表示仅监听或手动处理
* - 系统不会自动修改数据
*/
}
},
config:
{
submitCancel: true,
addUrl: "http://47.94.105.29:66/api/addDataListCase",
editUrl: "http://47.94.105.29:66/api/editDataListCase",
getUrl: "http://47.94.105.29:66/api/getDataListCase"
}
}