# 低码移动端组件开发指南 ## 概述 本文档介绍低码平台的移动端组件开发指南。移动端组件基于 Vue 进行开发,以 H5 形式运行,组件库采用 Vant。 **阅读前须知:** 在阅读本文档前,请先阅读《字段类型与物料组件开发指南.md》。移动端开发与浏览器端在整体设计、开发流程上保持一致,主要差异在于底层规划、文件目录、运行和初始化等差异。对于组件开发者,只需了按移动端的目录标准开发组件、配置组件即可。 本文档主要介绍移动端开发中的差异部分。关于功能开发的详细说明、开发标准与规范,请参考《字段类型与物料组件开发指南.md》。 ## 目录结构 移动端组件的相关配置文件位于 `packages/widget-mobile/src/config` 目录下,主要包含以下文件: ```text packages/widget-mobile/src/config/ ├── index.ts # 配置入口文件,注册移动端设计器和预览器配置 ├── Material.ts # 物料面板配置,定义组件在物料面板中的分类和展示 ├── RegisterWidget.ts # 组件注册配置,注册移动端组件的实现 ├── RegisterWidgetHelper.ts # 组件辅助工具注册配置 ├── RegisterSettings.ts # 组件设置配置 ├── WidgetType.ts # 组件类型枚举定义 ├── widget/ # 组件实现目录 │ ├── Root.vue # 页面根容器组件 │ └── TestWidget.vue # 测试组件示例 └── widget-helper/ # 组件辅助工具目录 └── TestWidgetHelper.ts # 测试组件辅助工具示例 ``` ### 主要文件说明 - **index.ts**: 配置入口,提供 `setMobileConfigAll()` 函数,用于注册设计器和预览器的配置。 - **Material.ts**: 定义组件在物料面板中的分类组织,通过 `getMaterialPanelConfig()` 返回物料配置数组。 - **RegisterWidget.ts**: 注册移动端组件的实现,将组件类型与对应的 Vue 组件进行映射。 - **WidgetType.ts**: 定义所有移动端组件的类型枚举,需要与后端定义的控件类型保持一致。 ## 开发流程 添加一个新的移动端物料组件,需要完成以下 6 个步骤的配置。下面以 `TestWidget` 组件为例,详细说明每个步骤的操作。 ### 步骤 1:添加组件类型枚举 在 `WidgetType.ts` 文件中添加组件类型枚举,枚举值需要与后端定义的控件类型保持一致。 ```typescript export enum WidgetType { // 测试组件 TestWidget = "TEST_WIDGET", // 你的新组件 // YourWidget = 'YOUR_WIDGET', } ``` ### 步骤 2:创建 Vue 组件 在 `widget/` 目录下创建组件的 Vue 文件,例如 `YourWidget.vue`。 ```vue ``` **注意事项:** - 组件使用 Vant 作为 UI 组件库 - 组件应支持响应式设计,适配移动端屏幕 ### 步骤 3:创建 WidgetHelper 配置 在 `widget-helper/` 目录下创建 Helper 配置文件,例如 `YourWidgetHelper.ts`。 Helper 文件需要实现 `WidgetHelper` 接口,主要包含以下方法: - `buildMaterialConfig()`: 定义组件在物料面板中的展示信息(图标、名称等) - `buildSettings()`: 定义组件的设置面板配置(属性、样式、事件等) - `buildWidget()`: 定义组件的默认 Schema 结构 - `buildSchemaController()`: 定义组件的 Schema 控制器方法 参考示例: ```typescript import type { WidgetHelper } from "~@/types/WidgetHelper"; import { WidgetType } from "../WidgetType"; const config: WidgetHelper = { type: WidgetType.TestWidget, buildMaterialConfig() { // 返回物料配置 }, buildSettings(params) { // 返回设置面板配置 }, buildWidget(params) { // 返回组件默认 Schema }, buildSchemaController() { // 返回 Schema 控制器方法 }, // 其他可选方法... }; export default config; ``` **详细说明请参考:** `widget-helper/TestWidgetHelper.ts` 文件的完整实现。 ### 步骤 4:注册组件 在 `RegisterWidget.ts` 文件的 `SYS_COMPS_MAP` 对象中添加组件映射。 ```typescript import TestWidget from "./widget/TestWidget.vue"; import { WidgetType } from "./WidgetType"; export const SYS_COMPS_MAP: Recordable = { [WidgetType.TestWidget]: { instance: TestWidget, }, // 你的新组件 // [WidgetType.YourWidget]: { // instance: YourWidget, // }, }; ``` ### 步骤 5:注册 Helper 在 `RegisterWidgetHelper.ts` 文件的 `SYS_MOBILE_WIDGET_HELPERS` 数组中添加 Helper 的导入和注册。 ```typescript import TestWidgetHelper from "./widget-helper/TestWidgetHelper"; export const SYS_MOBILE_WIDGET_HELPERS = [ TestWidgetHelper, // 你的新组件 // YourWidgetHelper, ]; ``` ### 步骤 6:添加到物料面板 在 `Material.ts` 文件的 `getMaterialPanelConfig()` 函数中添加组件到物料面板配置。 ```typescript import { MaterialCollapseTypeEnum } from "~@/types/MaterialPanelType"; import { WidgetType } from "./WidgetType"; export function getMaterialPanelConfig() { return [ { name: MaterialCollapseTypeEnum.Common, // 通用组件分类 widgetTypeList: [ WidgetType.TestWidget, // WidgetType.YourWidget, // 你的新组件 ], }, ]; } ``` **分类说明:** - `MaterialCollapseTypeEnum.Common`: 通用组件 - 其他分类可根据组件特性选择合适的分类 ### 完整开发清单 开发新组件时,请按以下清单逐项完成: - [ ] 步骤 1:在 `WidgetType.ts` 中添加枚举 - [ ] 步骤 2:创建 `widget/YourWidget.vue` 组件文件 - [ ] 步骤 3:创建 `widget-helper/YourWidgetHelper.ts` Helper 文件 - [ ] 步骤 4:在 `RegisterWidget.ts` 中注册组件 - [ ] 步骤 5:在 `RegisterWidgetHelper.ts` 中注册 Helper - [ ] 步骤 6:在 `Material.ts` 中添加到物料面板配置 ### 参考示例 完整示例可参考 `TestWidget` 组件: - 组件实现:`widget/TestWidget.vue` - Helper 配置:`widget-helper/TestWidgetHelper.ts` - 类型定义:`WidgetType.TestWidget` - 组件注册:`RegisterWidget.ts` 中的 `SYS_COMPS_MAP[WidgetType.TestWidget]` - Helper 注册:`RegisterWidgetHelper.ts` 中的 `SYS_MOBILE_WIDGET_HELPERS` - 物料配置:`Material.ts` 中的物料面板配置 ## BaseField / Field 三种使用方式说明 移动端字段容器在实际业务中有三种典型用法,本节重点说明 **`BaseField` 与 Vant `Field` 的配置与使用模式**。 整体上可以分为三种模式: - **模式一:基础模式(只用 BaseField,完全由 Schema 驱动)** - **模式二:插槽扩展模式(在 BaseField 上增加自定义插槽)** - **模式三:完全自定义模式(基于 useField + Vant Field 自行开发)** 下面分别说明三种模式的使用方式与适用场景。 ### 模式一:基础模式(只用 BaseField,零插槽开发) **示例代码:** ```vue ``` - **使用方式说明:** - 模板中直接使用 `BaseField`,传入由 `useField` 计算出的 `fieldProps` / `wrapperStyle` / `fieldSlots`; - 通过 `v-model` 和事件处理器完成双向绑定和事件派发; - `fieldProps` / `wrapperStyle` / `fieldSlots` 均由 `useField(schema, attrs, placeholder)` 等 Hook 计算而来。 - **字段配置来源:** - 标题、占位符、字数限制、校验规则、必填标记等,全部从 Schema(低码配置)中读取; - 开发者只需要通过 Helper 的 `buildSettings` / `buildWidget` 暴露字段配置即可。 - **适合场景:** - 只想快速用一个“通用输入组件”,只需要提供标准样式; **总结:** 模式一中,`BaseField` 被看作“通用字段容器”,开发者只需要准备好 `fieldProps` / `fieldSlots`,绝大多数展示和行为由平台内置。 ### 模式二:插槽扩展模式(BaseField + 自定义插槽) **示例代码:** ```vue 自定义标签 ``` - **使用方式说明:** - 继续使用 `BaseField` 作为外层容器,并保留基础属性和事件绑定; - 同时在 `` 内部编写插槽: - `#label`:自定义标签区域(可加入图标、说明、换行布局等); - `#left-icon` / `#right-icon`:替换为自定义图标/按钮(如搜索图标、清空按钮等); - `#input`:替换内部输入区域(可以是 ``,也可以是更复杂的组合,如“区号 + 手机号”)。 - **与基础模式的关系:** - 仍然完全复用 BaseField 的: - 表单布局(label 区、内容区、错误提示等); - 事件派发(focus / blur / valueChange); - Schema 驱动的属性(`fieldProps` / `fieldSlots`)。 - 只是把“局部渲染区域”交给业务组件来自定义。 - **适合人群/场景:** - 需要在标签上插入说明/图标,或改变标签的布局; - 需要在左右两侧放置单位、按钮、icon 等; - 需要对输入 DOM 做轻量改造,但又不希望重写整个 `Field` 逻辑。 **总结:** 模式二是在 **“不放弃 BaseField 能力”** 的前提下,通过插槽对部分区域进行增强,兼顾 **低码配置** 与 **少量编码定制**。 ### 模式三:完全自定义模式(useField + Vant Field) **示例代码:** ```vue 自定义 + {{ fieldSlots.labelData?.value?.label }} {{ fieldSlots.prependContent }} {{ fieldSlots.appendContent }} ``` - **使用方式说明:** - 不再使用 `BaseField`,直接使用 Vant 的 `Field` 组件: - `v-model="value"`:字段双向绑定; - `v-bind="fieldProps"`:透传由 `useField` 计算出的属性(如 placeholder、校验相关 props 等); - `:style="wrapperStyle"`:应用统一样式; - `@update:model-value="handleValueChange"`、`@focus="handleFocus"`、`@blur="handleBlur"`:自行接入事件。 - 使用 `fieldSlots` 提供的数据决定是否渲染 label / icon 等: - `fieldSlots.hasLabelSlot` + `fieldSlots.labelData?.value` 控制标签显隐、宽度、样式、必填星号等; - `fieldSlots.hasPrepend` / `fieldSlots.hasAppend` + 内容字段控制左右自定义区域。 - **与前两种模式的区别:** - 布局与 DOM 结构完全由业务组件掌控; - 只复用数据与配置层能力(`fieldProps` / `fieldSlots` / 事件 Hook),不复用 BaseField 的 UI 结构。 - **适合人群/场景:** - 对 DOM 结构、动画、样式有强定制需求; - 由前端开发者主导开发,低码配置主要提供字段元数据与校验规则; **总结:** 模式三是 **“只拿 Schema & Hook,不拿默认 UI”** 的高级用法,保留低码平台的数据/事件体系,同时对视觉与交互做彻底自定义。 --- **建议实践:** - 通用表单场景优先使用 **模式一(基础模式)**; - 需要少量 UI 扩展时优先考虑 **模式二(插槽扩展模式)**; - 仅在前两种模式无法满足需求时,再采用 **模式三(完全自定义模式)**,以控制维护成本。