表单页设计

云控专属可视化开发工具

  • 全网独家定制
  • 数据私有化部署
  • 支持多级菜单管理
  • 多用户分级管理
  • 二次开发成本直降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是否显示字数统计booleanfalse
clearable是否显示清除按钮booleanfalse
disabled是否禁用输入框booleanfalse
readonly是否只读booleanfalse
autocomplete浏览器自动完成功能string"off"
autofocus是否自动聚焦booleanfalse
tabindextab 键顺序string | number
validateEvent是否触发表单验证事件booleantrue
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显示行数number2
showWordLimit是否显示字数统计booleanfalse
clearable是否显示清除按钮booleanfalse
disabled是否禁用输入框booleanfalse
readonly是否只读booleanfalse
resize是否允许调整大小string"none"
autofocus是否自动聚焦booleanfalse
validateEvent是否触发表单验证事件booleantrue
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是否禁用booleanfalse
size单选框组尺寸string"default"
border是否显示边框booleanfalse
示例
{
  "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是否禁用booleanfalse
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是否多选booleanfalse
disabled是否禁用booleanfalse
clearable是否显示清除按钮booleanfalse
placeholder占位提示文字string""
filterable是否支持搜索过滤booleanfalse
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 | nullnull
type选择器类型string"date"
format展示格式string
valueFormat绑定值格式string
placeholder占位提示文字string""
disabled是否禁用booleanfalse
clearable是否显示清除按钮booleanfalse
editable输入框是否可编辑booleantrue
range是否为范围选择booleanfalse
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 | nullnull
isRange是否为时间范围选择booleanfalse
format显示格式string"HH:mm:ss"
valueFormat绑定值格式string"HH:mm:ss"
placeholder占位提示文字string""
disabled是否禁用booleanfalse
clearable是否显示清除按钮booleanfalse
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是否禁用booleanfalse
showAlpha是否显示透明度选择booleanfalse
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绑定的开关状态booleanfalse
disabled是否禁用booleanfalse
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绑定的数值number0
min最小值number
max最大值number
step步进值number1
disabled是否禁用booleanfalse
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是否禁用booleanfalse
clearable是否显示清除按钮booleanfalse
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当前评分number0
max最大分数number5
disabled是否禁用booleanfalse
allowHalf是否允许半星评分booleanfalse
showText是否显示文本说明booleanfalse
showScore是否显示数字评分booleanfalse
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 | array0
min最小值number0
max最大值number100
step步长number1
disabled是否禁用booleanfalse
range是否范围选择booleanfalse
showTooltip是否显示提示booleantrue
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是否多选booleanfalse
disabled是否禁用booleanfalse
clearable是否显示清除按钮booleanfalse
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是否有边框booleanfalse
shadow是否有阴影booleanfalse
示例
{
  "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是否禁用booleanfalse
loading是否加载中booleanfalse
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是否支持多文件上传booleanfalse
accept接受的文件类型string""
fileList已上传文件列表array[]
disabled是否禁用booleanfalse
showFileList是否显示文件列表booleantrue
示例
{
  "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是否禁用编辑booleanfalse
height编辑器高度(像素)number300
示例
{
  "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列数number24
gutter栅格间距number0
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、passwordstring"text""text"
placeholder输入框占位提示文字string"""请输入用户名"
maxlength最大输入长度number20
minlength最小输入长度number3
showWordLimit是否显示字数统计booleanfalsetrue
clearable是否显示清除按钮booleanfalsetrue
disabled是否禁用输入框booleanfalsefalse
readonly是否只读booleanfalsefalse
autocomplete浏览器自动完成功能string"off""off"
autofocus是否自动聚焦booleanfalsefalse
tabindextab 键顺序string | number"1"
validateEvent是否触发表单验证事件booleantruetrue
inputStyle输入框自定义样式对象object{}{ color: "#333", fontSize: "14px" }
size输入框尺寸,支持 small/default/largestring"default""default"
options选项数组(常用于 select、radio 等)Array<{ label: string; value: any }>[][ { label: "选项1", value: "1" }, { label: "选项2", value: "2" } ]
multiple是否多选booleanfalsefalse
filterable是否支持搜索筛选booleanfalsetrue
rows多行文本框行数,textarea 专用number24
resizetextarea 是否允许调整大小及方向string"none""vertical"
autosizetextarea 自动高度配置objectnull{ minRows: 2, maxRows: 6 }
buttonStyleradio 按钮样式string"outline""outline"
min数字类组件最小值number00
max数字类组件最大值number100100
step数字类组件步长number11
format日期格式,datePicker 专用string"""yyyy-MM-dd"
placeholderTime时间选择器占位提示string"""选择时间"
disabledDate禁用日期函数functionnull(date) => date < new Date()
showAlpha颜色选择器是否显示透明度booleanfalsefalse
activeColor颜色选择器主题色string"#409EFF""#409EFF"
checked开关状态,switch 组件专用booleanfalsefalse
icon按钮图标名string"""Check"
loading按钮加载状态booleanfalsefalse
text按钮文本string"""提交"
columns表格列配置Array<{ label: string; prop: string }>[][ { label: "姓名", prop: "name" }, { label: "年龄", prop: "age" } ]
data表格数据Array[][]
style容器样式object{}{ padding: "10px", backgroundColor: "#f5f5f5" }
height富文本编辑器高度number300300
action上传接口地址string"""/upload"
multipleUpload是否支持多文件上传booleanfalsefalse
showFileList是否显示文件列表booleantruetrue

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自定义配置项类型number1
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 是否添加冒号booleanfalse
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.modelreturn 新对象
  • 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"
  }
}