Widget → Component 自动化转换工具
概述
将 ArcGIS JS API 4.x 中基于命令式 Widget API 的工具,系统性地转换为 5.0 声明式
Web Components 组件。提供一套标准化的转换步骤、映射规则与可复用模板,确保每次
转换遵循一致的范式,且转换结果具备可维护性。
触发条件
以下任一场景触发本技能:
- 用户明确要求"转换 widget 为 component"或"用组件替换 widget"
- 用户提供旧版 HTML 文件要求升级到 5.0 Components
- 用户提到具体已弃用 widget 名称并要求替代方案(如 "TimeSlider 被弃用了")
- 用户要求将某个工具进行"组件化迁移"
转换工作流
第 1 步:分析源文件
读取源文件中与待转换 widget 相关的所有代码,提取以下关键信息:
- Widget 初始化代码 — 构造函数参数、容器的 DOM 选择器、配置对象
- 属性赋值 — 初始化后通过
widget.prop = value设置的属性 - 方法调用 —
widget.play(),widget.stop(),widget.destroy()等 - 事件监听 —
widget.on("event", handler),widget.watch("prop", handler) - View 绑定 —
widget.view = view或构造函数中的view: view - 模块导入 —
import ... from "@arcgis/core/widgets/Xxx.js"
第 2 步:确定目标组件
查阅 references/conversion-mapping.md 获取 Widget → Component 的完整映射表。
常见映射:
| Widget | Component | 状态 |
|---|---|---|
TimeSlider |
<arcgis-time-slider> |
可用 |
Sketch |
<arcgis-sketch> |
可用 |
Search |
<arcgis-search> |
可用 |
Zoom |
<arcgis-zoom> |
可用 |
Compass |
<arcgis-compass> |
可用 |
Home |
<arcgis-home> |
可用 |
LayerList |
<arcgis-layer-list> |
可用 |
Legend |
<arcgis-legend> |
可用 |
BasemapToggle |
<arcgis-basemap-toggle> |
可用 |
Expand |
<arcgis-expand> |
可用 |
如不确定,搜索官方文档:
https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-<name>/
第 3 步:执行结构化转换(9 个子步骤)
按以下顺序逐项转换,每步完成后验证:
A. CDN 替换
- 将 4.x 本地 CDN <link> 和 <script> 替换为 5.0 在线 CDN
- 添加 <script type="module" src="https://js.arcgis.com/5.0/"></script>
- 确保 renderCommon.js 从 CDN 加载
B. SceneView/MapView → 视图组件
- 将 new SceneView({ container: "viewDiv", ... }) 替换为 <arcgis-scene id="viewDiv" camera-position="...">
- 移除 SceneView/MapView 模块导入
- 将 view.map 赋值从构造函数移到外部:viewElement.view.map = map
- 将 await view.when() 替换为 await viewElement.viewOnReady()
- 在 viewOnReady() 之后调用 view.goTo() 重新定位相机
C. Widget 容器 → 自定义元素
- 在 HTML 中创建目标组件元素:<arcgis-xxx id="xxxEl"></arcgis-xxx>
- 删除旧的容器 <div id="xxxContainer"></div>(如组件自带容器)
- 保留包含组件的父级容器(如控制面板中的 <div>)
D. 构造函数参数 → 属性赋值
- 将构造函数中的 { container: "...", prop: value } 转换为组件元素属性
- container 参数不再需要(组件直接写在 HTML 中)
- 其他属性在 JS 中赋值:el.prop = value
- 详情见 references/conversion-mapping.md
E. View 绑定 → referenceElement
- 将 widget.view = view 替换为 el.referenceElement = "viewDiv"
- referenceElement 值对应视图组件(<arcgis-scene> 或 <arcgis-map>)的 id
F. 事件监听映射
- widget.on("event-name", handler) → el.addEventListener("arcgisEventName", handler)
- 事件名映射规则:"event-name" → "arcgisEventName"(camelCase + arcgis 前缀)
- widget.watch("prop", callback) → el.addEventListener("arcgisPropertyChange", (e) => { if (e.detail.name === "prop") callback() })
- 详情见 references/lifecycle-events.md
G. 方法调用兼容性检查
- 大部分 getter/setter 方法→属性直接赋值
- widget.play() → el.play()(大部分保持同名)
- widget.destroy() → el.remove() 或从 DOM 移除
- 详情见 references/conversion-mapping.md
H. 初始化时序调整
- 组件属性设置 → viewOnReady() → view.goTo() → componentOnReady()
- 详情见 references/lifecycle-events.md
I. 状态管理与 DOM 解耦
- 将命令式 DOM 操作(el.style.display = "none")改为条件渲染
- 将 UI 控件的事件绑定从 widget.on() 改为 component.addEventListener()
- 详情见 references/state-management.md
第 4 步:验证与测试
完成后检查以下项目:
- [ ] 所有 widget 模块导入已移除
- [ ] container 属性已替换为 HTML 中的自定义元素
- [ ] view 绑定已替换为 referenceElement
- [ ] view.when() 已替换为 viewElement.viewOnReady()
- [ ] 事件监听格式正确(arcgis 前缀 + camelCase)
- [ ] 初始化时序正确
- [ ] CDN 路径指向 5.0
资源文件
| 文件 | 用途 |
|---|---|
references/conversion-mapping.md |
Widget→Component 属性/方法/事件完整映射表 |
references/lifecycle-events.md |
生命周期对比与事件机制映射规则 |
references/state-management.md |
状态管理与 DOM 操作解耦重构方案 |
references/time-slider-example.md |
TimeSlider 完整转换案例(含逐行对比) |
references/voxel-silcesketch-example.md |
VoxelSilceSketch 转换案例(含自定义 widget 提取 + VoxelWasm→hitTest 替换) |
assets/component-base-template.html |
组件化 HTML 基础模板(新工具创建起点) |
扩展规范
向本技能添加新 widget 转换支持时,遵循以下流程:
- 在
references/conversion-mapping.md的映射表中新增对应 widget 行 - 在
references/下创建<widget-name>-example.md完整转换案例 - 如有特殊事件/方法映射,补充到
references/lifecycle-events.md - 如有特殊状态管理需求,补充到
references/state-management.md - 更新 SKILL.md 中的第 2 步映射表
与其他技能的关系
- arcgis-js-component:提供组件开发的基础知识和 API 参考。本技能专注转换流程
- 当转换需要组件 API 细节时,应同时加载 arcgis-js-component 技能