Install
openclaw skills install yida-dev钉钉宜搭低代码开发助手。用于创建表单和自定义页面、编写 JS 动作面板、使用 JS-API、配置数据源、设计流程自动化。适用于宜搭表单开发、JS 代码调试、API 集成等场景。
openclaw skills install yida-dev与传统前端不同,宜搭有独特的开发模式:
import Button、❌ 禁止 const Page = () => {...}this.$('textField_xxx') 操作已存在的组件宜搭组件的 fieldId 格式为:组件类型_随机后缀
| 组件类型 | fieldId 示例 |
|---|---|
| 单行文本 | textField_m2iqeyip |
| 多行文本/文本域 | textareaField_lu7rqky5 |
| 单选 | radioField_m2l8tqxr |
| 流水号 | serialNumberField_lr76bpi4 |
| 数字 | numberField_mbhl6h58 |
| 下拉选择 | selectField_mbhjt4zb |
| 日期 | dateField_ll0bcdf1 |
| 附件 | attachmentField_mbhjt4zd |
| 图片 | imageField_mbhjt4zl |
| 人员选择 | employeeField_mbhjt4zr |
| 人员多选 | employeeField_xxx + multiple: true |
| 部门选择 | departmentSelectField_lu7qx4i5 |
| 子表单/明细表 | tableField_mbhjt4zy |
| 地址 | addressField_mbhjt508 |
| 关联表单 | associationFormField_mbhjt50s |
| 区块 | pageSection_m2vthls5 |
| 按钮 | button_invoiceAdd |
| 发票组件 | ccInvoiceFieldComponentView_m2vv4aux |
| 多列布局 | columnsLayout_m2k6t8hx |
| 标签页 | tabsLayout_lkcfmpjv |
state.stathis.$('fieldId').setBehavior('HIDDEN')export function onChange({ value }) { } - 值变化事件export function didMount() { } - 页面加载完成宜搭组件 onChange 事件中修改状态需要延迟:
export function onChange({ value }) {
setTimeout(() => {
this.setState({ sta: value === '价款合同' })
}, 200)
}
组件属性中设置 behavior: "HIDDEN" 可隐藏字段(可用于数据传递)
组件属性中设置 behavior: "READONLY" 可设为只读
在组件属性中设置 valueType: "formula" + formula: "#{textField_xxx}"
{
"valueType": "formula",
"formula": "CONCATENATE(\"XMBH\",TEXT(TODAY(),\"yyMMdd\"),MID(TEXT(TIMESTAMP(NOW())),9,5))"
}
新增行时获取行数:
export function onAddClick(newGroupId) {
const count = this.$('tableField_xxx').getValue().length
this.$('textField_count').setValue(count + '条')
}
遍历子表单行,计算某列的不重复值数量:
export function onChange({ value, extra }) {
const subFormInst = this.$('tableField_xxx')
const items = subFormInst.getItems()
let distinctNum = []
items.forEach(item => {
const rowData = subFormInst.getItemValue(item)
if (rowData['textField_col'] && !distinctNum.includes(rowData['textField_col'])) {
distinctNum.push(rowData['textField_col'])
}
})
this.$('numberField_count').setValue(distinctNum.length)
}
人员选择变化时获取人员信息:
export function onChange({ value }) {
// value 是人员对象 { name, userId, ... }
this.$('textField_name').setValue(value.name)
}
用于分组显示,有标题头:
{
"componentName": "PageSection",
"props": {
"title": { "zh_CN": "基本信息" },
"behavior": "NORMAL", // 或 "HIDDEN" 隐藏整个区块
"showHeader": true
}
}
选择关联表单时自动填充其他字段:
{
"dataFillingRules": [
{ "sourceType": "SelectField", "targetType": "TextField", "source": "selectField_src", "target": "textField_target" }
]
}
设置 valueType: "linkage" + linkage 属性从其他表单获取数据
汇总子表单某列:
{
"valueType": "formula",
"formula": "SUM(#{numberField_column})"
}
单选切换时显示/隐藏字段(配置选项的联动规则)
失焦时执行校验(如手机号验证):
export function onBlur() {
let phone = this.$('textField_xxx').getValue()
if (!phone) return
if (!this.isPhoneNumber(phone)) {
this.utils.toast({ title: '请输入正确的手机号', type: 'warning' })
this.$('textField_xxx').setValue('')
}
}
export function isPhoneNumber(input) {
return /^1\d{10}$/.test(input.replace(/\D/g, ''))
}
设置 minValue 最小值:
{ "validation": [{ "type": "minValue", "param": "0" }] }
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| dataSource | 选项数据 | DataSource[] | [] |
| onChange | 值变化事件 | (value: string) => void | - |
| showSearch | 展开后能搜索 | boolean | true |
| filterLocal | 本地过滤 | boolean | - |
| mode | single/multi | string | single |
| hasClear | 清除按钮 | boolean | true |
| autoWidth | 菜单对齐 | boolean | true |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| onChange | 值变化事件 | ({value, extra}) => void | - |
| onAddClick | 新增行事件 | (newGroupId) => void | - |
| onDelClick | 删除行事件 | (groupId, item) => void | - |
| maxItems | 最大条数 | number | 50 |
| addButtonPosition | 新增位置 | 'top' | 'bottom' | bottom |
| layoutSetting.layout | 排列方式 | 'TILED' | 'TABLE' | TABLE |
| layoutSetting.theme | 主题 | 'zebra' | 'split' | 'border' | split |
| showIndex | 显示序号 | boolean | true |
const table = this.$('tableField_xxx')
table.getValue() // 获取所有行数据
table.getItems() // 获取行实例数组
table.getItemValue(item) // 获取某行数据
table.addItem() // 新增一行
table.removeItem(item) // 删除一行
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| precision | 小数位数 (0-20) | number | 0 |
| thousandsSeparators | 千分位 | boolean | false |
| innerAfter | 单位 | string | - |
| innerBefore | 前缀 | string | - |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| dataSource | 选项 | DataSource[] | [] |
| onChange | 值变化 | (value) => void | - |
| shape | 形状 | 'default' | 'button' | default |
| itemDirection | 排列 | 'hoz' | 'ver' | hoz |
| supportInverse | 反选 | boolean | false |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| layout | 分栏配置 | string | '6:6' |
| columnGap | 列间距 | number | 0 |
| rowGap | 行间距 | number | 0 |
| display | 手机排列 | 'VERTICAL' | 'HORIZONTAL' | VERTICAL |
布局格式: 2:2:2:2:4 (总和=12), 多行: 4:4:4\|6:6
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| type | 按钮类型 | 'primary'|'normal'|'secondary' | primary |
| content | 按钮文案 | string | 按钮 |
| size | 尺寸 | 'small'|'medium'|'large' | medium |
| behavior | 显示状态 | 'NORMAL'|'DISABLED'|'HIDDEN' | NORMAL |
| loading | 加载状态 | boolean | false |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| baseType | 基础图标 | string | smile |
| size | 尺寸 | 'xxs'|'xs'|'small'|'medium'|'large' | medium |
| useType | 使用自定义 | boolean | false |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| multiple | 多选 | boolean | false |
| showEmplId | 显示工号 | boolean | false |
| showAvater | 显示头像 | boolean | true |
| closeOnSelect | 选中后关闭 | boolean | false |
| onChange | 值变化 | ({value}) => void | - |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| format | 日期格式 | string | YYYY-MM-DD |
| type | 限制范围 | 'none'|'beforeToday'|'afterToday' | none |
| hasClear | 清除按钮 | boolean | true |
| returnType | 返回类型 | 'timestamp'|'string'|'moment' | timestamp |
| onChange | 值变化 | ({value}) => void | - |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| validationType | 格式 | 'text'|'mobile'|'email'|'chineseID' | text |
| maxLength | 字数上限 | number | 200 |
| hasClear | 清除按钮 | boolean | true |
| hasLimitHint | 计数器 | boolean | false |
| trim | 去空格 | boolean | false |
| onChange | 值变化 | ({value}) => void | - |
| 属性 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| rows | 行数 | number | 4 |
| autoHeight | 自动高度 | boolean | false |
| maxLength | 字数上限 | number | - |
人员字段自动填充当前登录人:
{ "valueType": "formula", "formula": "USER()" }
设置 dataFilterRules 过滤可选数据
在页面属性 → 数据校验 中配置,检测重复数据:
{
"displayRule": "EXIST(角色名称)",
"rule": "EXIST(#{formUuid}, \"textField_lenz6y7q\", #{textField_lenz6y7q})",
"message": "角色名称不能重复"
}
## 核心概念
### 全局变量 (State)
类似 React state,用于页面全局状态管理:
- 创建:在数据源面板 → 添加变量
- 读取:`this.state.name` 或 `state.name`(变量绑定时)
- 更改:`this.setState({ name: 'Jack' })`
- 特殊变量:`urlParams` - 获取 URL 参数
⚠️ 注意:setState 后可立即获取新值(不同于 React),但无回调函数
### 远程数据源
配置远程 API 进行异步请求:
```js
// 手动加载
this.dataSourceMap.apiName.load({ params }).then(res => {})
// 重新加载所有自动加载的数据源
this.reloadDataSource()
数据处理函数:
willFetch - 请求发送前修改参数fit - 响应数据适配didFetch - 请求成功后的数据处理onError - 错误处理export function didMount() { } // 页面加载完成
export function willUnmount() { } // 页面卸载前
给组件绑定动作事件,在动作面板实现处理逻辑:
export function onClick() {
const { name, age } = this.params // 获取绑定时设置的参数
}
内置规则 + 自定义校验函数:
function validateRule(value) {
if (/^杭州/.test(value)) return true
return false
}
手动触发校验:
this.$('textField_xxx').validate((errors, values) => {})
常用校验示例:
循环数据要求是数组,绑定变量获取循环数据:
this.item - 获取当前行数据this.index - 获取当前行索引容器组件绑定循环数据后可遍历渲染,内部组件通过变量绑定访问数据。
组件高级属性 → 是否渲染 → 绑定变量控制显隐
// 绑定 state.xxx 控制显示
state.urlParams.showName // 根据URL参数控制
两种方式:
| 术语 | 说明 |
|---|---|
| 全局变量 | 类似 React state,页面状态管理 |
| 远程 API | HTTP 接口配置,包含请求地址、参数、数据处理函数 |
| Schema | 低代码协议,描述页面/组件结构,类似 HTML |
| 组件唯一标识 | 组件的 fieldId,宜搭全局唯一标识 |
| 页面 | 独立展示界面(表单、报表、自定义页面) |
| 物料 | 可沉淀的前端能力(组件、区块、模板) |
| 业务组件 | 基于基础组件的业务领域组件 |
| 低代码业务组件 | 通过低代码编辑器搭建的业务组件 |
| 区块 | 组合多个组件/布局,可复制复用 |
| 模板 | 垂直业务领域的页面模板 |
触发类型:
节点类型:
⚠️ 仅限专属版
export function componentDidMount() { } // 渲染完成
export function componentDidUpdate() { } // 更新完成
export function componentDidCatch() { } // 错误捕获
export function componentWillUnmount() { } // 销毁前
this.props.xxx // 获取传入的属性
this.$('fieldId').get('propName') // 获取属性
this.$('fieldId').set('propName', value) // 设置属性
添加 function 类型属性作为事件回调,在组件内通过 this.props.xxx() 触发
debugger 断点调试cmd/ctrl + p → page.js 添加断点?__showDevtools 打开调试面板?__debug 查看/编辑 Schemaconst vConsole = 'https://g.alicdn.com/code/lib/vConsole/3.11.2/vconsole.min.js';
const js = document.createElement('script');
js.src = vConsole;
document.body.append(js);
js.onload = function() { window.vConsole = new window.VConsole(); };
前端页面调用,包括:
this.state.xxx / this.setState()this.dataSourceMap.xxx.load() / this.reloadDataSource()this.$(fieldId).getValue() / this.$(fieldId).setValue()this.utils.toast() / this.utils.dialog() / this.utils.router.push()this.$(fieldId).validate() / this.$(fieldId).setValidation()远程数据源配置中调用,用于表单数据操作:
POST /v1/form/saveFormData.jsonPOST /v1/form/updateFormData.jsonPOST /v1/form/deleteFormData.jsonGET /v1/form/searchFormDatas.jsonPOST /v1/process/startInstance.json需手动加载:https://g.alicdn.com/dingding/dingtalk-jsapi/2.10.3/dingtalk.open.js
需通过钉钉开放平台调用,需要鉴权:
// ✅ 正确:操作已存在的组件(通过 fieldId)
this.$('textField_m2iqeyip').getValue()
this.$('textField_m2iqeyip').setValue('hello')
// ❌ 错误:不要声明/导入组件
// const MyButton = () => {...} // 禁止!
this.setState({ key: 'value' })
const value = this.state.key
// URL 参数(默认全局变量)
const param = this.state.urlParams.xxx
export function didMount() { } // 页面加载完成
export function willUnmount() { } // 页面卸载前
this.dataSourceMap.api.load(params).then(res => { })
this.reloadDataSource()
this.utils.toast({ title: '成功', type: 'success' })
this.utils.router.push('/pageId')
this.utils.getLoginUserId()
?__showDevtools 打开调试面板?__debug 查看 Schemadebugger 断点console.log 输出调试信息需通过钉钉开放平台调用,需要创建应用并获取授权。
| 接口 | 路径 | 说明 |
|---|---|---|
| 发起审批 | POST /yida/v1/process/startInstance.json | processCode, formUuid, formDataJson |
| 删除流程 | POST /yida/v1/process/delete.json | processInstanceId |
| 终止流程 | POST /yida/v1/process/terminate.json | processInstanceId |
| 查询实例 | GET /yida/v1/process/getById.json | processInstanceId |
| 查询实例列表 | GET /yida/v1/process/getInstanceIds.json | formUuid, instanceStatus |
| 接口 | 路径 | 说明 |
|---|---|---|
| 保存数据 | POST /yida/v1/forms/saveData.json | formUuid, formDataJson |
| 更新数据 | POST /yida/v1/forms/updateData.json | formInstId, formDataJson |
| 查询数据 | GET /yida/v1/forms/listData.json | formUuid, searchFieldJson |
| 获取子表数据 | GET /yida/v1/forms/listSubTableData.json | formUuid, formInstId, tableFieldId |
// 发起流程
const params = {
processCode: "TPROC--CFYJ5HYUN89NJ1JW3IXBI7A95RXM3652O9MKK3",
formUuid: "FORM-CFYJ5HYUN89NJ1JW3IXBI7A95RXM3552O9MKK2",
formDataJson: JSON.stringify({ textField_kkm9o5cd: "123" })
};
this.dataSourceMap.myDatasource.load(params);
常见表单开发场景:
宜搭页面使用 JSON Schema 定义,可以直接粘贴到设计器中。
{
"type": "nodeSchema",
"componentsMap": {},
"componentsTree": [
{
"componentName": "PageSection",
"props": { ... },
"children": [ ... ]
}
]
}
{
"componentName": "TextField",
"props": {
"fieldId": "textField_xxxxx",
"label": { "type": "i18n", "zh_CN": "字段名称", "en_US": "字段名称" },
"behavior": "NORMAL",
"valueType": "custom",
"validation": [{ "type": "required" }],
"placeholder": { "type": "i18n", "zh_CN": "请输入", "en_US": "请输入" },
"maxLength": 200,
"visibility": ["PC", "MOBILE"]
}
}
{
"componentName": "NumberField",
"props": {
"fieldId": "numberField_xxxxx",
"label": { "type": "i18n", "zh_CN": "金额", "en_US": "金额" },
"precision": 2,
"step": 1,
"behavior": "NORMAL",
"valueType": "custom",
"validation": [
{ "type": "required" },
{ "type": "minValue", "param": 0 },
{ "type": "maxLength", "param": 25 }
]
}
}
{
"componentName": "DateField",
"props": {
"fieldId": "dateField_xxxxx",
"label": { "type": "i18n", "zh_CN": "日期", "en_US": "日期" },
"format": "YYYY-MM-DD",
"behavior": "NORMAL",
"valueType": "custom",
"validation": [{ "type": "required" }]
}
}
{
"componentName": "SelectField",
"props": {
"fieldId": "selectField_xxxxx",
"label": { "type": "i18n", "zh_CN": "选项", "en_US": "选项" },
"mode": "single",
"showSearch": true,
"behavior": "NORMAL",
"valueType": "custom",
"defaultDataSource": {
"customStashOptions": [
{ "text": { "zh_CN": "选项一", "en_US": "选项一" }, "value": "选项一", "sid": "serial_xxx" }
]
}
}
}
{
"componentName": "RadioField",
"props": {
"fieldId": "radioField_xxxxx",
"label": { "type": "i18n", "zh_CN": "类型", "en_US": "类型" },
"itemDirection": "hoz",
"behavior": "NORMAL",
"valueType": "custom",
"dataSource": [
{ "text": { "zh_CN": "选项A", "en_US": "选项A" }, "value": "A", "sid": "serial_a" },
{ "text": { "zh_CN": "选项B", "en_US": "选项B" }, "value": "B", "sid": "serial_b" }
]
}
}
{
"componentName": "EmployeeField",
"props": {
"fieldId": "employeeField_xxxxx",
"label": { "type": "i18n", "zh_CN": "申请人", "en_US": "申请人" },
"multiple": false,
"behavior": "NORMAL",
"valueType": "custom",
"userRangeType": "ALL",
"validation": [{ "type": "required" }]
}
}
{
"componentName": "AssociationFormField",
"props": {
"fieldId": "associationFormField_xxxxx",
"label": { "type": "i18n", "zh_CN": "关联数据", "en_US": "关联数据" },
"behavior": "NORMAL",
"multiple": false,
"associationForm": {
"formUuid": "FORM-XXXXXXXX",
"appType": "APP_XXXXXXXX"
},
"validation": [{ "type": "required" }]
}
}
{
"componentName": "Image",
"props": {
"fieldId": "image_xxxxx",
"src": "https://example.com/image.jpg",
"width": 100,
"height": 100,
"fit": "cover"
}
}
{
"componentName": "Text",
"props": {
"fieldId": "text_xxxxx",
"content": { "type": "i18n", "zh_CN": "文本内容", "en_US": "文本内容" },
"__style__": ":root { font-size: 16px; font-weight: 600; }"
}
}
{
"componentName": "LinkBlock",
"props": {
"fieldId": "linkBlock_xxxxx",
"link": { "type": "url", "url": "https://example.com", "isBlank": true },
"__style__": ":root { margin: 10px; }"
}
}
{
"componentName": "Div",
"props": {
"fieldId": "div_xxxxx",
"__style__": ":root { padding: 20px; background: #fff; }"
}
}
{
"componentName": "PageSection",
"props": {
"fieldId": "pageSection_xxxxx",
"title": { "type": "i18n", "zh_CN": "基本信息", "en_US": "基本信息" },
"showHeader": true,
"behavior": "NORMAL"
}
}
{
"componentName": "ColumnsLayout",
"props": {
"fieldId": "columnsLayout_xxxxx",
"layout": "4:4:4"
},
"children": [
{ "componentName": "Column", "props": { "fieldId": "column_1" } },
{ "componentName": "Column", "props": { "fieldId": "column_2" } },
{ "componentName": "Column", "props": { "fieldId": "column_3" } }
]
}
| 属性 | 说明 | 值 |
|---|---|---|
| behavior | 组件状态 | NORMAL, READONLY, HIDDEN, DISABLED |
| valueType | 值类型 | custom, formula, linkage |
| validation | 校验规则 | required, minValue, maxLength, customValidate |
| formula | 公式 | CONCATENATE, TODAY, TIMESTAMP, USER, SUM 等 |
| format | 日期格式 | YYYY-MM-DD, YYYY-MM-DD HH:mm:ss |
字段 ID 格式:组件类型_随机后缀,例如:
textField_abc123numberField_def456selectField_ghi789当前应用:APP_F22M8EK6I2HZTBIYV3U5