V1.0.0
Skip to content

WForm 组件

表单容器组件,基于 WinDesignNext WForm 封装,用于包裹 WFormItem 和 WInput 等表单相关组件。支持通过 rules 定义校验规则,配合 WFormItemprop 实现表单验证。

WForm 会自动注册实例到 processorformId 为组件的 id),可通过 processor.getFormInstance(formId) 获取表单实例,在外部事件处理中调用 validate()resetFields() 方法。

基础用法

下面的示例演示了一个带验证的表单:输入框和下拉选择均设为必填(rules + prop)。点击提交按钮时,在外部事件处理中通过 processor.getFormInstance() 获取表单实例并调用 validate() 方法校验;点击重置按钮时调用 resetFields() 方法重置表单。

两种事件处理方式

WForm 本身不产生事件,事件由表单内的 WInput 和 WButton 触发。支持两种事件监听方式:

方式一:window.addEventListener

通过监听 win-design-a2ui-event 窗口事件。detail 中提供了 getFormInstance 方法:

typescript
window.addEventListener('win-design-a2ui-event', async (e) => {
  const { message, respond, getFormInstance } = e.detail;

  if (message.userAction.name === 'onSubmit') {
    // 通过 detail 中的 getFormInstance 获取表单实例
    const formInstance = getFormInstance('form_001');
    if (formInstance) {
      const valid = await formInstance.validate();
      if (!valid) {
        respond([]); // 校验不通过,返回空消息
        return;
      }
    }
    // 校验通过,继续处理提交逻辑...
    respond([]);
  }

  if (message.userAction.name === 'onReset') {
    const formInstance = getFormInstance('form_001');
    if (formInstance) {
      formInstance.resetFields();
    }
    respond([]);
  }
});

window 事件监听中,使用 respond 代替 event.resolve,使用 getFormInstance 代替 processor.getFormInstancedetail 中还提供了 updateDataModelupdateComponentProp 等方法。

方式二:processor.onEvent

通过 processor.onEvent() 注册事件回调,适用于 Vue 应用内部:

typescript
processor.onEvent(async (event) => {
  const eventName = event.message.userAction?.name;

  if (eventName === 'onSubmit') {
    const formInstance = processor.getFormInstance('form_001');
    if (formInstance) {
      const valid = await formInstance.validate();
      if (!valid) {
        event.resolve([]);
        return;
      }
    }
    // 校验通过,继续处理...
    event.resolve([]);
  }
});

输入事件(WInput)

输入时触发,context 携带当前输入值:

json
{
  "action": {
    "event": {
      "name": "onNameInput",
      "context": [
        { "key": "value", "value": { "literalString": "用户输入的值" } }
      ]
    }
  }
}

提交事件(WButton)

点击提交按钮时,通过 path 从 dataModel 读取最新的输入值,并通过 processor.getFormInstance() 获取表单实例进行校验:

json
{
  "action": {
    "event": {
      "name": "onSubmit",
      "context": [
        { "key": "name", "value": { "path": "/name" } },
        { "key": "age", "value": { "path": "/age" } }
      ]
    }
  }
}
typescript
// 监听提交事件,校验后再处理
processor.onEvent(async (event) => {
  const eventName = event.message.userAction?.name;
  const context = event.message.userAction?.context;

  if (eventName === 'onSubmit') {
    // 获取表单实例并校验(formId 为 WForm 的 id)
    const formInstance = processor.getFormInstance('form_001');
    if (formInstance) {
      const valid = await formInstance.validate();
      if (!valid) {
        event.resolve([]);
        return;
      }
    }

    // 校验通过,继续处理提交逻辑
    console.log('表单数据:', context);
    event.resolve([]);
  }
});

Props API

WForm

属性名类型默认值说明
idstring-组件唯一标识(必填)
componentstringWForm组件类型(必填)
sizestring''表单尺寸
disabledbooleanfalse是否禁用所有表单项
labelPositionstringright标签位置
labelWidthstring''标签宽度
labelSuffixstring''标签后缀
inlinebooleanfalse是否行内表单
inlineMessagebooleanfalse是否行内显示校验信息
statusIconbooleanfalse是否显示校验状态图标
showMessagebooleantrue是否显示校验信息
validateOnRuleChangebooleantrue规则改变时是否立即校验
hideRequiredAsteriskbooleanfalse是否隐藏必填星号
rulesobject{}表单校验规则
childrenstring[]-子组件 ID 列表(WFormItem)

WFormItem

属性名类型默认值说明
idstring-组件唯一标识(必填)
componentstringWFormItem组件类型(必填)
labelstring''标签文本
propstring-对应 model 中的字段名(校验用)
labelWidthstring''标签宽度(覆盖 Form 设置)
contentPositionstring''内容对齐方式
childrenstring[]-子组件 ID 列表

path 支持说明

通用绑定格式见 path 数据绑定速查

WForm / WFormItem 自身属性不支持 path 绑定,但内部表单控件通过 modelValue.path 与 dataModel 关联:

子组件path 用法说明
WInput / WInputNumbermodelValue: { "path": "/field" }字段值双向绑定
WSelect / WCascadermodelValue + 可选 dataSource选中值与动态选项
WButton(提交)action.event.context[].value.path提交时读取最新表单值

WFormItem.prop 需与 modelValue.path 去掉前导 / 后的字段名一致,以便校验生效。详见下方 三者对应关系


组件关系

WForm
├── WFormItem (label: "姓名", prop: "name")
│   └── WInput (modelValue.path: "/name")
├── WFormItem (label: "类型", prop: "type")
│   └── WSelect (modelValue.path: "/type")
├── WFormItem (label: "年龄", prop: "age")
│   └── WInput (modelValue.path: "/age")
└── WFormItem
    └── WButton (提交)
  • WForm:表单容器,管理全局表单配置
  • WFormItem:表单项容器,绑定标签和校验规则
  • WInput:输入框,通过 modelValue.path 绑定 dataModel
  • WSelect:下拉选择,通过 modelValue.path 绑定 dataModel 对象;optionsvalue 为对象时需配置 valueKey
  • WButton:提交按钮,通过 context 中的 path 读取最新值

表单验证

WForm 支持基于 rules 的表单校验:

  • 字段失焦(blur)或值变化(change)时自动校验
  • 提交时通过 processor.getFormInstance(formId).validate() 进行全量校验

三者对应关系

表单验证的核心是三个属性值必须保持一致:

WForm rules 的 key         →  "name"       /  "type"
WFormItem prop             →  "name"       /  "type"
WInput/WSelect modelValue.path →  "/name"  /  "/type"  (去掉前导 / 即为字段名)

WFormmodel 无需手动设置,A2UI 会自动从 dataModel 构建。

工作流程

用户输入 → WInput 将值同步到 dataModel["name"]
         → 触发 blur/change → WFormItem 根据 rules["name"] 自动校验

用户点击提交按钮
         → 外部事件处理中调用 processor.getFormInstance(formId).validate()
         → 遍历所有 WFormItem 的 rules,逐一校验
         → 全部通过 → 继续处理提交逻辑
         → 存在失败 → 阻止提交,对应字段显示红色错误提示

配置步骤

1. 在 WForm 中定义 rules

json
{
  "id": "form_001",
  "component": "WForm",
  "labelWidth": "100px",
  "rules": {
    "name": [
      { "required": true, "message": "请输入姓名", "trigger": ["blur"] }
    ],
    "age": [
      { "required": true, "message": "请输入年龄", "trigger": ["blur"] },
      { "type": "number", "message": "年龄必须为数字", "trigger": ["blur"] }
    ]
  },
  "children": ["form_item_name", "form_item_age", "form_item_submit"]
}

2. 在 WFormItem 中设置 prop

prop 的值需要与 rules 中的 key 对应,同时与 dataModel 中的路径名一致:

json
{
  "id": "form_item_name",
  "component": "WFormItem",
  "label": "姓名",
  "prop": "name",
  "children": ["input_name"]
}

3. 外部事件处理中调用校验

json
{
  "id": "btn_submit",
  "component": "WButton",
  "type": "primary",
  "action": {
    "event": {
      "name": "onSubmit",
      "context": [
        { "key": "name", "value": { "path": "/name" } },
        { "key": "age", "value": { "path": "/age" } }
      ]
    }
  },
  "child": "btn_text"
}
typescript
processor.onEvent(async (event) => {
  if (event.message.userAction?.name === 'onSubmit') {
    const formInstance = processor.getFormInstance('form_001');
    if (formInstance) {
      const valid = await formInstance.validate();
      if (!valid) {
        event.resolve([]);
        return;
      }
    }
    // 校验通过,继续处理提交逻辑...
  }
});

校验规则(rules)

每条规则支持以下字段(基于 async-validator):

字段类型说明
requiredboolean是否必填
messagestring校验失败时的提示信息
triggerstring[]触发校验的方式,如 ["blur", "change"]
minnumber最小长度/值
maxnumber最大长度/值
typestring值类型,如 "string""number""email"
patternRegExp正则表达式校验
validatorfunction自定义校验函数

关于 trigger

  • "blur" — 输入框失去焦点时触发校验
  • "change" — 输入框值变化时触发校验
  • 推荐对必填项使用 ["blur"],对格式校验使用 ["blur", "change"]

常见校验规则示例

json
{
  "rules": {
    "name": [
      { "required": true, "message": "请输入姓名", "trigger": ["blur"] }
    ],
    "phone": [
      { "required": true, "message": "请输入手机号", "trigger": ["blur"] },
      {
        "pattern": "/^1[3-9]\\d{9}$/",
        "message": "手机号格式不正确",
        "trigger": ["blur"]
      }
    ],
    "email": [
      { "required": true, "message": "请输入邮箱", "trigger": ["blur"] },
      {
        "type": "email",
        "message": "邮箱格式不正确",
        "trigger": ["blur", "change"]
      }
    ],
    "age": [
      { "required": true, "message": "请输入年龄", "trigger": ["blur"] },
      {
        "type": "number",
        "min": 0,
        "max": 150,
        "message": "年龄范围 0-150",
        "trigger": ["blur"]
      }
    ]
  }
}

提交按钮、普通按钮与重置按钮

WButton 点击时触发事件,表单校验/重置在外部事件处理中自行调用:

json
// 提交按钮
{
  "id": "btn_submit",
  "component": "WButton",
  "type": "primary",
  "action": { "event": { "name": "onSubmit" } },
  "child": "btn_submit_text"
}

// 重置按钮
{
  "id": "btn_reset",
  "component": "WButton",
  "action": { "event": { "name": "onReset" } },
  "child": "btn_reset_text"
}

外部事件处理:

typescript
processor.onEvent(async (event) => {
  const eventName = event.message.userAction?.name;

  if (eventName === 'onSubmit') {
    // 获取表单实例并校验
    const formInstance = processor.getFormInstance('form_001');
    if (formInstance) {
      const valid = await formInstance.validate();
      if (!valid) {
        event.resolve([]);
        return;
      }
    }
    // 校验通过,继续提交逻辑...
  }

  if (eventName === 'onReset') {
    // 获取表单实例并重置
    const formInstance = processor.getFormInstance('form_001');
    if (formInstance) {
      formInstance.resetFields();
    }
    event.resolve([]);
  }
});

formId 为 WForm 的 id,WForm 会自动注册实例到 processor