
在制造类 ERP 系统中,树形结构是支撑核心业务的底层载体:多级物料分类、多层级产品 BOM 清单、组织架构、客户分级、工序工艺路线全部依赖树形控件承载数据。传统开发中,前端递归渲染树、后端递归查询树形数据、单元格自定义渲染、行内编辑、拖拽新增子节点等功能需要数千行代码实现,前后端联调、分页、复选联动、持久化布局配置工作量巨大。
WebBuilder 内置高度封装的 Tree 树形表格组件,依托自研 XWL 声明式配置,同时支持远程数据库树形加载、本地静态树形数据、单元格多列自定义渲染、行内编辑、批量增删改同步入库,一套组件覆盖 ERP 所有树形业务场景,无需手写递归、无需单独封装树接口,大幅降低制造 ERP 中 BOM、物料分类模块开发成本。
基于官方完整 Tree 示例 XWL 代码,平台提供两种树形数据加载方案,分别对应 ERP 静态基础档案、动态业务单据树形场景。
{
cname: "tree",
cid: "commonRemoteTree",
url: "demo-source?xaction=listAreaTree",
height: "15em"
}通过url绑定服务端接口,后端 SQL 递归查询物料分类、BOM 层级、部门组织等树形数据,动态返回嵌套树形 JSON 结构。
ERP 落地场景:
物料分类档案、客户层级、供应商分类、车间工序路线、组织架构等数据量较大、需要持久化数据库的树形档案,打开页面自动异步加载树形节点,支持分页、筛选、动态刷新。
配套serverScript服务端脚本,一段 SQL 即可实现递归树形查询:
serverScript(){
let xaction = Params.xaction;
const actions = {
listAreaTree(){
// 递归查询物料分类树形数据,parent_id关联父子层级
let treeData = Wb.getTreeRows({
sql: "select sid, area_name, parent_id from erp_material_cat order by sid",
parentField: "parent_id",
idField: "sid",
textField: "area_name"
});
Wb.send(treeData);
}
};
if(actions[xaction]) actions[xaction]();
}通过localData直接在 XWL 内定义嵌套数组,无需请求后端接口,适合固定层级、数据不常变更的树形展示。
示例中大陆 - 国家两层结构可直接改造为 ERP 成品 - 半成品 - 原材料多层 BOM 静态预览:
localData: [
{
text: '成品-电机总成', _icon: 'product', remark: '主成品', area: 1, percentage: 1,
items: [
{ text: '半成品-电机外壳', _leaf: true },
{ text: '半成品-电机线圈', _leaf: true, items:[{text:'铜线原材料',_leaf:true}] }
]
}
]优势:页面加载零接口请求,用于 BOM 弹窗快速预览、固定行业分类展示,轻量化无后端依赖。
普通树形组件仅支持单列文本展示,无法承载 BOM 用量、损耗率、成本、勾选状态等多维度业务字段。WebBuilder Tree 原生支持多列表格树形,可配置多级表头、冻结列、百分比格式化、单元格自定义渲染、复选框、开关、操作按钮,完全匹配制造 BOM 业务复杂展示需求。
resizable: true, // 列宽拖拽调整
gridLine: true, // 网格线
headerLine: true, // 表头分割线
columnsSortable: true, // 列排序
stateId: "wb.miscTree",// 布局持久化,用户调整列宽刷新页面保留
linkedCheck: true, // 父子节点复选联动(BOM全选/反选刚需)
frame: true, // 边框容器
pagingBar: true // 树形分页,大数据量BOM不卡顿Land Areas下拆分Percentage占比、Area用量双列,ERP BOM 可复用该结构:// 用量数值单元格:低于阈值标红底色+图标
render(value, data, column, el){
if (value < 10000000) {
el.parentNode.cls = 'w-succ-bgcolor-row';
el.cls = 'w-error-color';
value = '* ' + value.intText;
}
let wrapEl = el.addEl('w-row w-align-center');
wrapEl.addEl('w-item-icon w-icon icon-thumb');
wrapEl.addEl('w-text').textContent = value;
}ERP 业务改造:
checkBox: "int", // 数字型勾选值,存库0/1
checkBox: "roTrue", // 只读勾选框
toggleCol: {render: 内置开关组件} // 自制/外购物料切换开关适配 BOM 场景:批量勾选子物料生成采购申请、标记物料自制 / 外购属性。
5. 行内操作按钮列,单节点快速业务操作
单元格嵌入按钮组:设置、新增子件、下载 BOM 明细,双击节点弹窗查看物料档案,对应代码事件:
itemdblclick(item, e, options){
Wb.tip(item.data.text + ' row double clicked');
}双击 BOM 子物料,弹窗跳转物料档案详情页,一站式业务联动。
示例editableTree是 ERP 工程模块核心组件,支持树形节点全生命周期编辑,自带顶部工具栏,实现新增根节点、新增子件、编辑字段、删除节点、一键同步数据库,完整覆盖 BOM 版本维护、物料分类新增业务。
表格
按钮 | 快捷键 | ERP 业务用途 |
|---|---|---|
新增 (Ctrl+E) | addRecord | 新增成品 BOM 根节点 |
编辑 (Ctrl+J) | startEdit | 修改物料名称、损耗率 |
删除 (Ctrl+D) | delRecords | 移除废弃子物料 |
新增子件 | addData | 给当前成品添加下级半成品 / 原材料 |
保存 (Ctrl+S) | tree.sync | 树形所有修改批量同步数据库 |
columns : [{
cname: "column",
text: "物料名称",
fieldName: "area_name",
expander: true,
editor: {cname: "text", required: true} //文本框编辑名称
},{
cname: "column",
text: "上级分类",
fieldName: "parent_id",
editor: {
cname: "select",
url: "demo-source?xaction=areaSearch" //下拉树形选择父节点
}
}]BOM 场景适配:
点击保存按钮调用tree.sync,平台自动收集新增、编辑、删除的树形节点数据,统一提交服务端,服务端脚本批量处理层级数据,自动维护父子parent_id关联关系,彻底解决传统开发树形保存层级错乱、递归保存复杂难题。
({
cname: "module",
cid: "erp_material_cat_tree",
title: "物料分类树形管理",
description: "物料多级分类维护,适配ERP物料主数据",
// 服务端树形查询、新增、更新、删除逻辑
serverScript(){
let xaction = Params.xaction;
const actions = {
// 加载完整物料分类树形
listAreaTree(){
let tree = Wb.getTreeRows({
sql: "select sid,cat_name,parent_id,sort from erp_material_cat order by sort",
idField:"sid",parentField:"parent_id",textField:"cat_name"
});
Wb.send(tree);
},
// 下拉选择父分类数据源
areaSearch(){
Wb.sendRows("select sid,cat_name from erp_material_cat");
},
// 树形批量保存
saveTree(){
let payload = Wb.payloadParams;
Wb.treeSync({
tableName:"erp_material_cat",
idField:"sid",
parentField:"parent_id",
data:payload
});
Wb.send("ok");
}
};
if(actions[xaction]) actions[xaction]();
},
items : [{
cname: "viewport",
cid: "viewport1",
layout: "grid1",
items : [{
cname: "label",
cid: "mainLabel",
text: "物料多级分类管理",
cls: "w-title3"
},
{
cname: "title",
cid: "editableTreeTitle",
title: "分类树形(支持新增、编辑、子分类、批量保存)"
},
{
cname: "tree",
cid: "materialCatTree",
columnsSortable: true,
editable: true,
height: "30em",
multiSelect: true,
sorters: "sort",
url: "erp_material_cat_tree?xaction=listAreaTree",
pagingBar: true,
frame: true,
linkedCheck: true,
stateId: "erp.materialCatTree",
// 顶部操作工具栏
tbar: {
cname: "toolbar",
cid: "tbar",
isProperty: true,
items : [{
cname: "item",
cid: "addBtn",
text: "新增一级分类",
icon: "add",
keys: "Ctrl+E",
events: {
click(){
app.materialCatTree.addRecord({ cat_name: '新分类', parent_id: null, sort: 0 });
}
}
},
{
cname: "item",
cid: "editBtn",
text: "编辑分类",
icon: "edit",
keys: "Ctrl+J",
events: {
click(){
let rec = app.materialCatTree.firstItem;
if(rec){
rec.startEdit("cat_name");
rec.highlight();
}
}
}
},
{
cname: "item",
cid: "delBtn",
text: "删除分类",
icon: "delete",
keys: "Ctrl+D",
events: {
click(){
app.materialCatTree.delRecords();
}
}
},
{cname: "divider"},
{
cname: "item",
cid: "addChild",
text: "新增子分类",
icon: "insert",
events: {
click(){
let tree = app.materialCatTree;
let sel = tree.getSelection()[0];
if(!sel){
Wb.tipWarn("请先选中父分类");
return;
}
sel.expand(()=>{
sel.addData({ cat_name:"新子分类",parent_id:sel.data.sid,sort:0 });
})
}
}
},
{cname: "divider"},
{
cname: "item",
cid: "saveBtn",
text: "保存全部修改",
icon: "save",
keys: "Ctrl+S",
events: {
click(){
app.materialCatTree.sync({
url: "erp_material_cat_tree?xaction=saveTree",
success() { Wb.tipSucc("分类保存完成"); }
});
}
}
}
]
},
// 树形多列表头
items : [{
cname: "array",
cid: "columns",
items : [{
cname: "column",
cid: "catNameCol",
text: "分类名称",
fieldName: "cat_name",
expander: true,
width: -1,
editor: {
cname: "text",
cid: "editor",
isProperty: true,
required: true
}
},
{
cname: "column",
cid: "sidCol",
text: "分类编码",
fieldName: "sid",
width: "12em",
editor: {cname: "text",isProperty:true,required:true}
},
{
cname: "column",
cid: "parentIdCol",
text: "上级分类",
fieldName: "parent_id",
width: "18em",
editor: {
cname: "select",
url: "erp_material_cat_tree?xaction=areaSearch",
textField: "cat_name",
valueField: "sid",
required: true
}
},
{
cname: "column",
cid: "sortCol",
text: "排序号",
fieldName: "sort",
width: "10em",
editor: {cname: "number",isProperty:true,minValue:0}
}
]
}
]
},
{
cname: "component",
cid: "miscDescComp",
html: "<div>物料分类功能说明:</div>\n<ul>\n <li>支持无限级物料分类,原材料/半成品/成品分层管理</li>\n <li>可拖拽调整列宽,布局自动持久化保存</li>\n <li>支持新增一级分类、选中节点新增子分类</li>\n <li>行内直接编辑名称、编码、上级分类、排序</li>\n <li>一键批量保存所有新增/修改/删除数据,自动维护层级关系</li>\n</ul>",
textSelectable: false
}
]
}
]
})对比维度 | WebBuilder Tree 树形组件 | 传统前后端分离开发 | 通用拖拽低代码平台 |
|---|---|---|---|
树形数据递归渲染 | XWL 配置自动处理,无需前端递归函数 | 手写递归渲染组件,层级越深代码越复杂 | 仅支持 2 级简单树形,多层级扩展受限 |
父子节点联动勾选 | linkedCheck 属性一键开启 | 手动监听勾选事件,递归遍历子节点赋值 | 不支持父子联动复选,需自定义 JS 大量代码 |
树形多列表格展示 | 原生 Tree+Column 复合组件,支持多级表头 | 树形组件 + 自定义表格混合开发,兼容性差 | 树形仅单列,无法展示 BOM 多业务字段 |
行内编辑 + 工具栏操作 | 内置 editor 编辑器、tbar 工具栏配置 | 单独封装编辑弹窗、新增弹窗,十余个接口 | 仅简单文本编辑,不支持下拉选择父节点 |
批量树形保存 | tree.sync 自动处理增删改,内置 treeSync 数据库方法 | 手动区分新增 / 修改 / 删除,递归更新 parent_id 层级 | 无批量同步能力,只能单条保存 |
布局持久化 | stateId 自动保存列宽、排序、展开状态 | 前端本地存储手动编写存储逻辑 | 无布局记忆功能,刷新页面重置样式 |
树形结构是制造 ERP 的业务骨架,BOM、物料分类等核心功能的开发效率直接决定整套系统落地速度。WebBuilder Tree 组件跳出常规树形控件仅支持单列展示的局限,以 XWL 声明式配置融合树形递归渲染、多列表格、行内编辑、批量持久化能力,一套组件兼顾展示、编辑、存储全流程需求。
依托平台 Tree 组件,开发人员无需钻研复杂递归算法、树形数据联动逻辑,仅通过可视化配置即可实现专业级工业 ERP 树形业务模块,真正实现快速、稳定、易维护的企业级应用开发。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。