更新时间:2024-08-20 GMT+08:00
分享

自定义组件开发指南

在这个快速发展的前端开发时代中,组件化是构建可维护和可扩展应用程序的关键。

本章节帮助您了解自定义模板结构及开发流程。

模板结构介绍

  • public文件夹通常是用来存放 Web 应用程序的静态资源。
  • src文件夹是用来存放源代码文件,它包含assets和components两个子文件夹。
    • assets:作为存放项目特定资源的地方。
    • components:用来存放应用程序的组件代码,如自定义的类、服务、工具类等。

模板文件介绍

所有的自定义组件都在src/components文件夹里面内开发,模板内提供了两个预置模板componentA和componentB,可直接在模板基础上进行开发,如需更多可复制添加。

图1 默认组件

components都包含三个文件,一个index.js,一个*.vue文件和一个componentBundle.json文件,其中index.js 和 componentBundle.json这两个文件名字不可更改。

图2 components文件夹
  • componentBundle.json:用于定义一组组件的元数据,包括组件的配置、依赖关系、版本信息等。
  • index.js:作为应用程序的入口文件,即程序启动时首先执行的脚本。
  • *.vue:用于定义 Vue 组件,包括模板(HTML)、脚本(JavaScript)和样式(CSS)。

组件协议结构规范

组件协议结构规范用于描述组件的关键信息和配置项,对应组件的components字段。

表1 组件协议结构规范

字段

说明

类型

name

组件名称,已“i18n”形式配置。

Object

component

组件名。

String

icon

组件图标。

String

screenshot

快照。

String

description

组件介绍描述。

String

npm

组件NPM包信息,会根据此描述引入npm源组件。

Object

npm.package

npm包名。

-

npm.exportName

需要从npm包中import的名称。

-

npm.version

package 的版本。

-

npm.destructuring

是否以结构方式import。

-

npm.script

ESModule格式的JS文件CDN地址。

String

npm.css

样式文件CDN地址。

String

group

组件分组。

String

schema

组件元数据(定义属性、事件等)。

Object

configure

组件的属性信息。

Object

version

组件版本。

Object

组件元数据结构规范

组件元数据规范用于描述组件的对外API:属性、事件等,对应组件的schema字段。

表2 组件元数据结构规范

字段

说明

类型

properties

组件暴露的配置属性。

Array <Object>

events

组件暴露的事件。

Object

组件暴露配置属性项结构(properties[0])。

表3 置属性项结构

字段

说明

类型

label

配置分类名。

Object

description

配置分类描述。

Object

collapse

配置项超出数量时收缩展示。

Object

content

属性项。

Array

content[0].property

配置的组件属性名称。

string

content[0].type

属性值的类型。

string

content[0].defaultValue

属性值的默认值。

string| boolean | number

content[0].label

展示的属性配置label

Object

content[0].cols

-

-

content[0].rules

属性值的校验规则。

Array

content[0].labelPosition

配置面板文本定位。

string

content[0].hidden

是否展示改属性配置。

boolean

content[0].required

是否必须配置该属性项。

boolean

content[0].readOnly

该属性项是否只读。

boolean

content[0].disabled

是否禁用配置该属性项。

boolean

content[0].widget

配置属性值的渲染组件和props。

Object

content[0].device

使用该属性的设备 e.g. pc 端,移动端,可选:pc,mobile。

string

widget.component

使用哪个组件来配置属性值,比如可选:MetaInput MetaSelect。

string

widget.props

属性值组件的 props。

Object

使用模板开发样例

本示例中的imgbutton组件是使用nodejs开发前端的组件。以下若无特殊说明,均基于VSCode工具,按照imgbutton组件的功能点来介绍自定义组件的开发过程。

  1. 下载自定义组件模板,将自定义组件模板包解压。
  2. 修改工程定义文件“package.json”,将“name”修改成“imgbutton-package”,“version”修改为“0.0.1”,保存并退出。

    图3 修改包名及版本

  3. 修改src文件夹下的“components”文件夹及文件名,将“componentA”改为“imgButton”,如图所示。

    图4 修改文件夹及文件名

  4. 打开“componentBundle.json”文件,文件包含两个字段components和snippets。

    • components字段为一个对象,描述组件的关键信息和配置项。

      例如:编写组件的注册信息,包括组件的名称、文件路径、版本号等。

      "id": 1,
          "version": "2.4.2",//组件版本号
          "name": {
            "zh_CN": "img组件A" // 属性显示名称
          },
          "component": "imgButton",//组件名
          "icon": "custom-component",//组件图标
          "description": "图像按钮",//组件介绍描述
          "doc_url": "",
          "screenshot": "",
          "tags": "",
          "keywords": "",
          "dev_mode": "proCode",
          "npm": {
            "package": "",
            "version": "",
            "script": "",
            "css": "",
            "dependencies": null,
            "exportName": "imgButton"//需要从npm包中import的名称
          },

      编写组件元数据,例如:组件属性、事件等。

      "schema": {
            "properties": [
              {
                "name": "0",
                "label": {
                  "zh_CN": "基础属性"// 属性显示名称
                },
                "content": [
                  {
                    "property": "size",
                    "label": {
                      "text": {
                        "zh_CN": "size"// 属性显示名称
                      }
                    },
                    "description": {
                      "zh_CN": "尺寸"
                    },
                    "required": true,
                    "readOnly": false,
                    "disabled": false,
                    "cols": 12,
                    "labelPosition": "top",
                    "type": "string",
                    "defaultValue": "default",// 默认值
                    "widget": {
                      "component": "MetaSelect",
                      "props": {
                        "options": [
                          {
                            "label": "large",
                            "value": "large"
                          },
                          {
                            "label": "default",
                            "value": "default"
                          },
                          {
                            "label": "small",
                            "value": "small"
                          }
                        ]
                      }
                    }
                  },
                  {
                    "property": "text",
                    "label": {
                      "text": {
                        "zh_CN": "type"// 属性显示名称
                      }
                    },
                    "description": {
                      "zh_CN": "类型"
                    },
                    "required": true,
                    "readOnly": false,
                    "disabled": false,
                    "cols": 12,
                    "labelPosition": "top",
                    "type": "string",
                    "defaultValue": "我是图像组件A",// 默认值
                    "widget": {
                      "component": "MetaInput",
                      "props": {}
                    }
                  }
                ],
                "description": {
                  "zh_CN": ""
                }
              }
            ],
            "events": {
              "onClick": {
                "label": {
                  "zh_CN": "点击时触发"// 事件名称
                },
                "description": {
                  "zh_CN": "点击时触发"// 事件描述信息
                },
                "type": "event",// 事件的type为event
                "functionInfo": {
                  "params": [],
                  "returns": {}
                },
                "defaultValue": ""
              }
            }
          }
      编写组件属性额外信息,例如:是否是容器,是否支持循环,是否支持快渲染等。
       "configure": {
            "loop": true,// 是否支持循环
            "condition": true,// 是否在画布中渲染
            "styles": true,
            "isContainer": true,//是否为容器
            "isModal": false,
            "isPopper": false,
            "nestingRule": {
              "childWhitelist": "",
              "parentWhitelist": "",
              "descendantBlacklist": "",
              "ancestorWhitelist": ""
            },
            "isNullNode": false,
            "isLayout": false,
            "rootSelector": "",
            "shortcuts": {
              "properties": [
                "type",
                "size"
              ]
            },
            "contextMenu": {
              "actions": [
                "copy",
                "remove",
                "insert",
                "updateAttr",
                "bindEevent",
                "createBlock"
              ],
              "disable": []
            },
            "invalidity": [
              ""
            ],
            "clickCapture": true,
            "framework": "Vue"
          },
    • snippets字段为一个对象,其中snippets.group为该自定义组件的分组标识。不同的组件可以拥有相同的group。
      "snippets": {
          "group": "自定义组件分类标题",
          "componentSnippets": {
            "name": {
              "zh_CN": "img组件A"
            },
            "icon": "custom-component",
            "screenshot": "",
            "snippetName": "imgButton",
            "schema": {
              "children": [
                {
                  "componentName": "Text",
                  "props": {
                    "text": "按钮文本"
                  }
                }
              ]
            }
          }
        }

    components和snippets字段更多的协议请参考物料资产包协议

  5. 打开imgButton.vue文件。开发实际的imgButton组件,确保可以在componentBundle.json中被引用。

    例如:
    // <template> 标签内编写组件的 HTML 结构。
    <template>
      <div :class="['show',size]">
        <h2>
          {{ text }}
        </h2>
        <Button :class="size" type="primary">这个是图像按钮组件</Button>
      </div>
    </template>
    
    // <script> 标签内定义组件的逻辑,包括组件名称、数据等。
    <script>
    export default {
      props: {
        size: {
          type: String,
          default: 'default'
        },
        text: {
          type: String,
          default: '我是img组件A'
        }
      }
    }
    </script>
    
    // <style> 标签内编写组件的 CSS 样式。
    <style scoped lang="less">
    h2 {
      color: red;
    }
    .show {
      color: #f99;
      padding-bottom: 50px;
    }
    
    .small {
      font-size: 12px;
    }
    
    .default {
      font-size: 16px;
    }
    
    .large {
      font-size: 18px;
    }
    </style>

  6. 修改应用开发工具控件定义文件,src\components\imgButton\index.js,将控件定义文件中的“componentA”修改为“imgButton”,“TestA”修改为“imgButton”,修改后效果如下图所示。

    图5 修改定义文件

  7. 修改main.js文件,确保导出组件成功,“componentA”修改为“imgButton”,“TestA”修改为“imgButton”,修改后效果如下图所示。

    图6 修改main.js文件

  8. 开发完成后,执行构建,例如,使用VSCode执行npm run build命令进行构建。

    如果执行命令时提示找不到,请先使用“npm install”安装依赖。

    构建完成后将在本地生成压缩包,即开发完成的组件物料包。
    图7 执行构建

    打包的物料包会取根目录package.json里面的name和version进行命名压缩包名字,格式为“name+version”。例如,name为“imgbutton-package”,version为“0.0.1”,则压缩包名称为“imgbutton-package-0.0.1”。

    图8 命名规则
    图9 生成物料包

相关文档