AI 驱动的 Vue3 应用开发平台 深入探究(十一):物料系统之创建自定义物料组件

0 阅读11分钟

创建自定义物料组件

自定义物料组件使你能够用自己的 Vue 组件扩展 VTJ 的低代码设计器,使其可用于视觉设计、属性配置和运行时渲染。本指南演示了如何创建、配置和注册与 VTJ 设计器生态系统无缝集成的自定义物料。

物料系统架构

VTJ 的物料系统遵循模式驱动架构,其中组件元数据与 Vue 组件实现分开定义。这种分离允许同一组件在不同 UI 库中使用,同时保持一致的设计器行为。物料系统由三个核心层组成:Vue 组件实现层、物料描述模式层和设计器注册层。

flowchart TB
    subgraph 实现层
        A1[Vue 组件]
        A2[组件逻辑与模板]
    end
    subgraph 模式层
        B1[MaterialDescription]
        B2[属性与设置器]
        B3[事件与插槽]
        B4[代码片段]
    end
    subgraph 注册层
        C1[物料索引]
        C2[组件集合]
        C3[物料导出]
        C4[设计器注册]
        D1[视觉设计器]
        D2[属性面板]
        D3[运行时渲染器]
    end

    A1 --> A2
    A1 -.->|被引用| B1
    B1 --> B2
    B1 --> B3
    B1 --> B4
    B1 -->|被导出| C1
    C1 --> C2 --> C3 --> C4
    C4 --> D1
    C4 --> D2
    C4 --> D3

物料系统实现了双向集成:组件可以从组件面板拖拽,通过属性设置器配置,并在运行时渲染。这种架构确保自定义物料的行为与内置的 Element Plus、Ant Design Vue 和 Vant 组件完全一致。

理解 MaterialDescription 模式

MaterialDescription 接口定义了组件在设计器内运行所需的完整元数据。该模式包括组件标识、属性定义、事件处理程序、插槽配置和初始化代码片段。每个字段在设计器工作流程中都有特定用途,从组件发现到属性编辑和运行时渲染。

核心标识字段包括 namelabelcategoryId,它们控制组件在设计器组件面板中的显示方式。name 字段必须与 Vue 组件的注册名称完全匹配,而 label 提供人类可读的显示文本。通过 categoryId 进行的组件分类将组件组织到逻辑组中,以便更好地导航。

属性定义使用 props 数组,其中每个属性指定其名称、标签、默认值、数据类型,最重要的是,设置器类型。设置器决定了属性如何在属性面板中编辑,选项范围从简单的字符串输入到复杂的配置对象。系统支持基本设置器和自定义组件设置器,用于处理复杂的属性类型。

事件和插槽声明使设计器能够公开组件交互点。事件声明为简单事件的字符串数组,或包含详细参数描述的 MaterialEvent 对象。插槽支持带有参数信息的命名声明,允许设计器可视化子组件可以放置的位置。

物料创建分步流程

创建自定义物料涉及四个不同阶段:准备 Vue 组件、定义物料模式、注册到物料系统和集成到设计器。每个阶段建立在前一个阶段之上,最终形成一个功能完整的自定义物料。

graph LR
    subgraph 阶段1详情
        A1[创建Vue组件] --> A2[定义Props接口] --> A3[导出组件]
    end
    subgraph 阶段2详情
        B1[创建MaterialDescription] --> B2[配置Props与Setters] --> B3[定义Events与Slots] --> B4[创建Snippet]
    end
    subgraph 阶段3详情
        C1[导入模式] --> C2[添加到组件数组] --> C3[导出物料对象]
    end
    subgraph 阶段4详情
        D1[导入物料] --> D2[注册到设计器] --> D3[在设计器中测试]
    end

    阶段1详情 --> 阶段2详情 --> 阶段3详情 --> 阶段4详情

阶段 1:准备 Vue 组件

任何自定义物料的基础都是结构良好的 Vue 组件。组件应遵循 Vue 3 Composition API 模式,具有清晰的 prop 定义和 emit 声明。重要的是,组件必须以一致的命名导出,以匹配物料模式的 name 字段。

Vue 组件应使用 TypeScript 接口或运行时 prop 对象定义其 props。这确保了类型安全,并使物料模式能够正确引用 prop 名称。对于发出事件的组件,使用带有显式类型定义的 defineEmits 来记录事件负载结构。

阶段 2:定义物料模式

在物料目录中创建一个 TypeScript 文件来定义组件的物料描述。该模式捕获设计器集成所需的所有元数据。首先从 @vtj/core 导入 MaterialDescription 类型,然后构造一个描述组件功能的对象。

props 数组是模式中最详细的部分,定义了每个可配置属性。对于通用 props,使用共享工具函数(如 size()type())来保持物料库的一致性。对于自定义 props,指定名称、标签、默认值、数据类型和适当的设置器类。

事件声明为标准事件的简单字符串数组,或在需要记录事件参数时声明为 MaterialEvent 对象。插槽遵循类似模式,支持简单字符串声明和高级插槽使用的详细参数规范。

阶段 3:注册到物料系统

定义物料模式后,通过将其导入到适当的索引文件中来注册到物料系统。将组件描述导入到相关的类别索引文件中(例如,Element Plus 组件的 element/index.ts),将其添加到组件数组,并确保正确导出。

物料系统使用 Material 对象将所有组件与包元数据捆绑在一起。该对象包括包名称、版本、显示标签、组件库引用和所有已注册组件的数组。setPackageName 工具函数自动将包信息附加到每个组件描述。

阶段 4:设计器集成

最后一步是将注册的物料与 VTJ 设计器集成。将物料包导入设计器配置并注册到物料注册表。设计器将自动发现并在组件面板中显示自定义组件,包括属性编辑器、事件处理程序和插槽可视化。

通过将自定义物料拖拽到画布上、配置其属性并验证运行时行为来进行测试。确保所有设置器正确渲染,事件按预期触发,插槽正确接受子组件。

属性设置器和配置

属性设置器定义了组件属性如何在设计器的属性面板中编辑。VTJ 提供了一套全面的内置设置器,涵盖常见数据类型和配置模式,并支持自定义设置器以满足特殊用例。

内置设置器

基本设置器处理基本数据类型:StringSetter 用于文本输入,NumberSetter 用于数值,BooleanSetter 用于切换开关,SelectSetter 用于预定义选项。这些设置器自动处理类型转换和验证,确保属性值符合组件的预期。

复杂设置器管理更复杂的数据结构:JsonSetter 用于 JSON 对象配置,ArraySetter 用于列表管理,IconSetter 用于图标选择,ColorSetter 用于颜色选择。这些设置器提供针对各自数据类型定制的专用 UI 控件。

组合设置器允许单个属性使用多种设置器类型,指定为数组。当属性接受不同数据类型或想要提供多种编辑界面时,这很有用。例如,工具提示属性可能接受字符串(简单工具提示)和对象(高级配置)。

设置器类型使用场景数据类型
StringSetter文本输入、标签、URLstring
NumberSetter计数器、尺寸、IDnumber
BooleanSetter切换、标志、状态boolean
SelectSetter枚举选项string
JsonSetter复杂配置object
IconSetter图标选择string/object
ColorSetter颜色定义string
ArraySetter列表管理array

自定义设置器

对于特殊属性编辑要求,通过实现 MaterialSetter 接口创建自定义设置器。自定义设置器接收当前属性值,并在用户修改值时发出更改事件。此模式允许完全控制属性编辑体验。

自定义设置器对于需要特殊验证、多步骤配置或与外部服务集成的特定于域的属性特别有价值。例如,数据源属性可能使用自定义设置器,该设置器查询可用数据源并在可搜索界面中显示它们。

高级物料功能

除了基本属性配置外,VTJ 物料还支持增强设计器集成和开发者体验的高级功能。这些功能包括初始化代码片段、嵌套组件规则和文档集成。

初始化代码片段

代码片段定义了将组件拖拽到画布时的初始结构和默认值。此功能通过提供合理的默认值来加速开发,开发人员可以随后自定义这些默认值。代码片段支持嵌套组件结构,使创建组合组件(如按钮组或表单字段集)变得容易。

snippet 属性接受一个 Partial<NodeSchema> 对象,该对象定义组件的初始状态。这包括组件名称、属性值、子组件和默认插槽内容。设计良好的代码片段提供演示组件使用模式的可用起点。

父级和子级约束

物料可以通过 parentIncludeschildIncludes 属性定义放置约束。这些约束控制组件可以放置的位置以及它们可以接受哪些子组件,防止无效配置并引导用户采用正确的使用模式。

parentIncludes 指定哪些父组件可以包含此组件,接受有效父名称数组或布尔值。将其设置为 false 会阻止组件放置在任何位置,这对于抽象组件很有用。同样,childIncludes 控制组件中允许哪些子组件。

文档集成

doc 属性链接组件文档,使设计人员能够直接从属性面板访问全面的使用指南。这种集成将视觉设计环境与详细文档连接起来,减少了上下文切换并提高了开发人员生产力。

文档链接应指向稳定的永久 URL。对于开源项目,链接到官方组件库文档。对于自定义组件,维护可从设计器轻松访问的单独文档。

最佳实践和模式

遵循既定模式可确保自定义物料与 VTJ 设计器生态系统无缝集成并提供一致的用户体验。

可重用的属性定义

将通用属性定义提取到共享工具中以保持组件间的一致性。物料库包括 size()type()effect() 等辅助函数,用于标准化常用属性。为自己的通用属性遵循此模式,以减少重复并确保统一行为。

// shared/props.ts 示例
export function alignment(name: string = "align"): MaterialProp {
  return {
    name,
    title: "对齐方式",
    defaultValue: "left",
    setters: "SelectSetter",
    options: ["left", "center", "right"],
  };
}

设置器选择策略

根据属性的语义含义和预期值选择设置器。对于具有固定值的枚举选项,使用带有显式选项的 SelectSetter。对于范围或连续值,使用专用设置器(如 SliderSetterColorSetter)。将 JsonSetter 保留给真正不适合简单模式的复杂对象。

如果有疑问,首选更简单的设置器,它们清楚地传达属性的用途。复杂的 JSON 对象可能会让设计人员感到困惑,并可能导致配置错误。尽可能考虑创建多个简单属性而不是一个复杂的对象属性。

组件组织

按功能和依赖关系组织物料。将相关组件分组在同一文件中(例如,按钮和按钮组),并按组件类别(表单、数据、导航)组织文件。此结构镜像了内置物料组织,使维护更容易。

保持组件实现和物料模式之间的清晰分离。Vue 组件应只关注渲染和行为,而物料模式描述设计器集成。这种分离允许同一组件在不同物料库中使用。

现实示例:自定义操作组件

来自 @vtj/uiXAction 组件展示了复杂的自定义物料实现。此组件通过工具提示、徽章和下拉功能扩展了基本按钮功能,展示了如何通过精心设计的物料模式公开复杂的组件行为。

物料模式定义了 15 个属性,涵盖每个扩展功能的配置。属性使用适当的设置器:SelectSetter 用于模式和背景等枚举选择,IconSetter 用于图标配置,JsonSetter 用于菜单和下拉菜单等复杂嵌套配置。事件包括标准点击事件和下拉菜单项的命令事件。

组件实现使用 Vue 的 composition API 和自定义 hooks(useTooltipuseBadgeuseDropdown)来管理每个功能的状态和行为。这种模块化方法保持了组件的可维护性,同时通过物料模式暴露了丰富的配置选项。

后续步骤

创建了自定义物料组件后,探索高级主题以进一步扩展 VTJ 实现:

  • 物料模式配置:深入了解高级模式选项和验证规则
  • 自定义设置器和属性编辑器:为复杂用例创建专用属性编辑器
  • 插件系统开发:构建扩展设计器功能的插件
  • 集成第三方库:将外部 Vue 组件库合并到 VTJ 中

物料系统为构建全面的低代码设计体验提供了基础。通过遵循内置物料中演示的模式并利用可扩展架构,你可以创建与 VTJ 设计器和运行时环境无缝集成的自定义组件。

参考资料