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

新建并开发自定义组件

操作场景

当系统预置的组件无法满足用户需求时,用户可自定义组件包进行上传,在页面中进行使用。在开发自定义组件前,请仔细阅读自定义组件开发规范章节内容,了解组件的开发规范。下面以开发网站中常用的柱状图(vue2+Echarts)组件为例,向您介绍如何开发自定义组件。

本节使用的示例组件开发过程中使用了前端开发框架VueEcharts,请提前了解。

图1 最终呈现效果

开发自定义组件

  1. 下载图表模板。

    1. 参考登录AstroCanvas界面中操作,登录AstroCanvas界面。
    2. 单击页面右上角的“管理”,进入AstroCanvas管理页面。
    3. 在左侧导航栏中,选择“页面资产管理 > 组件模板”。
      表1 组件模板列表

      组件模板名称

      功能

      EchartsWidgetTemplate

      基于Echarts实现的一个柱状图组件模板,包含基本配置项、单击系列的事件交互、数据对接等能力。

      SelectWidgetTemplate

      基于elmentUI和Vue2实现一个通用的下拉框组件模板,包含基本配置项、交互、数据对接等能力。

      widgetVueTemplate

      当需要使用Vue library时,请选用该模板。

      widgetPropertyTemplate

      当需要自定义组件的一些属性时,请选用该模板。自定义属性会显示在组件的属性配置界面。

      widgetActionTemplate

      当自定义组件需要添加动作属性时,请选用该模板。

      事件和动作都是Widget的配置属性,用于实现Widget之间的交互。例如,单击某个Widget内的按钮,另外一个Widget需要进行数据更新操作,或者是需要跳转到同个应用下的其他页面,这时需要通过事件和动作的机制来实现。单击按钮是触发一个事件,该Widget需要选用“widgetEventTemplate”模板,数据更新操作或者页面跳转操作是一个动作,该Widget需要选用“widgetActionTemplate”模板。

      widgetEventTemplate

      当自定义组件需要添加事件属性时,请选用该模板。

      widgetBridgeTemplate

      当自定义组件需要通过桥接器调用后台数据时,请选用该模板。

      widgetPageMacroTemplate

      当需要使用页面宏来存储变量时,请选用该模板。

    4. 在组件模板列表中,单击“EchartsWidgetTemplate”,进入模板详情页。
      图2 选择EchartsWidgetTemplate模板
    5. 单击“下载”,将EchartsWidgetTemplate组件模板包下载到本地。
    6. 解压已下载的组件模板包,认识组件结构。
      表2 组件文件结构

      文件名

      文件说明

      EchartsWidgetTemplate.js

      组件逻辑文件,整个Widget的渲染核心JS,在组件编辑状态和页面最终的发布运行态都会被加载执行。主要包含的预置API说明请参见表3

      EchartsWidgetTemplate.editor.js

      组件属性定义文件,负责组件在编辑状态时需要渲染的界面和逻辑。“*.editor.js”只在组件编辑状态被加载,主要包含:

      • propertiesConfig方法:主要负责组件配置页面中右侧的属性配置逻辑。
      • create方法:仅在组件首次被创建时调用一次。

      EchartsWidgetTemplate.css

      组件的样式文件,在该文件中编写组件的CSS样式。

      EchartsWidgetTemplate.ftl

      组件DOM结构文件,需要在服务端提前渲染的部分可以写在此文件中,相当于HTML文件,负责样式展示。

      packageinfo.json

      组件的元数据描述文件。

      • widegtApi name:组件的名称。
      • widgetDescription:组件的描述信息。
      • authorName: :组件的作者信息。
      • localFileBasePath:组件本地调测路径。
      • i18n:指定组件的国际化资源文件(本例模板中未体现)。
      • requires:依赖的库名称和版本号。
      • width:在绝对布局高级页面中,添加该组件时的默认宽度,单位为px,不填写默认为200px(本例模板中未体现)。
      • height:在绝对布局高级页面中,添加该组件时的默认高度,单位为px,不填写默认为200px(本例模板中未体现)。

      messages-zh/messages-en.json

      组件的国际化资源文件,用于配置多语言(本例模板中未体现)。

      表3 组件名.js中预置API说明

      分类

      API及说明

      组件实例预置API

      • init方法:主要包含组件渲染需要初始化数据的入口函数。
      • render方法:负责整个组件渲染的业务逻辑方法。
      • getConnectorProperties:获取桥接器属性的配置值。
      • getConnectorInstanceByName:通过桥接器的变量名称获取桥接器实例,其中“APIConnector”类型为String,表示桥接器的变量名称。
      • ConnectorIns.process(renderCbk, errCbk):通过桥接器实例调用process函数,主要作用为发起调用服务的请求和处理返回结果信息。
        • 在通过process函数发起请求前,需设置桥接器实例的requestParams属性为请求的参数,例如:ConnectorIns.requestParams = param;
        • 参数renderCbk,类型为Function,当返回结果信息后调用该函数,用于处理返回信息。
        • 参数errCbk,类型为Function,调用该函数来处理错误。
      • ConnectorIns.query(param):通过桥接器实例调用process函数,主要作用为发起调用服务的请求和处理返回结果信息,参数说明如下:
        • param:请求参数。
        • 其返回结果为Promise对象。
      • getProperties:用于返回该组件的自定义属性值。

        开发Widget时,可以给组件自定义属性,在开发界面可对这些属性进行配置,通过getProperties方法可返回自定义属性值。例如,var properties = thisObj.getProperties()。

      • getContainer:用于返回渲染该组件的容器dom节点。

        代码示例:var elem = thisObj.getContainer (),然后通过jquery去查询组件中某个dom节点时,可通过$("#id", elem)的方式来获取。

      • getWidgetBasePath:用于返回该组件静态资源的根路径。

        例如某个组件的静态资源路径为“https://10.10.10.1:12900/default/0000000000NABzEjpNIH/assets/bundle/widget/172a6056501-a6f8ce1f-2ed9-4a9a-b883-251aaac14e0a/v1591923270914/test0609.js”,执行thisObj.getWidgetBasePath()返回“https://10.10.10.1:12900/default/0000000000NABzEjpNIH/assets/bundle/widget/172a6056501-a6f8ce1f-2ed9-4a9a-b883-251aaac14e0a/v1591923270914” 。

      • getMessages:返回该组件国际化配置文件中定义的国际化文件内容。需要配置vue和vueI18n使用。

        例如开发组件时定义了messages-en.json和messages-zh.json国际化文件。thisObj.getMessages()返回的就是这两个文件中定义的国际化内容。

      • hideWidget:隐藏该组件的dom结构。在预览态调用该方法可以隐藏Widget。

        例如,执行thisObj.hideWidget()方法隐藏该组件的dom结构。

      • showWidget:显示该组件的dom结构。在预览态调用该方法可以展示Widget。

        例如,执行thisObj.showWidget()方法显示该组件的dom结构。

      • SITE_ROOT_PATH:为预置参数,用于获取当前站点URL地址的根路径。站点和应用是一对一的关系,当创建应用时,系统默认会创建并分配一个站点。

        假如,某个页面的URL地址为“https://10.10.10.1:12900/magno/render/cool__app_0000000000NABzEjpNIH/page1”,则使用SITE_ROOT_PATH获取的根路径为“/magno/render/cool__app_0000000000NABzEjpNIH”。

      • triggerEvent:用于触发事件,参数说明如下:
        • eventName:指定触发的事件名称。
        • {}:为事件触发时传递的参数赋值,例如{param: value}。

      Studio对象预置API

      • Studio.registerWidget:用来定义组件。
      • Studio.registerConnector:用来定义桥接器。
      • Studio.registerEvents:用于注册事件,只有通过此API注册后的事件才会在组件的事件列表中展现。参数说明如下:
        • thisObj:当前组件实例对象,指为该组件注册事件。
        • eventName:事件名称,应该与触发事件API中的第一个参数保持一致。
        • Event Label:事件标签名,在事件列表中展示的事件标题。
        • []:定义该事件触发时传递的参数模型,例如[{"name": "param"}] 。
      • Studio.registerAction:用来注册动作。只有通过此API注册后的事件才会在组件的动作列表中展现。参数说明如下:
        • thisObj:当前组件实例对象,指为该组件注册动作。
        • actionName:动作名称。
        • Action Label:动作标签名,在动作列表中展示的动作标题。
        • []:事件触发时传入的参数。
        • $.proxy(this.receiveActionCbk, this):该动作的回调函数,在回调函数中定义该动作的执行逻辑。
        • []:此参数在开发过程中置为空数组即可。
      • Studio.registerRouter:用来定义路由。
      • Studio.inReader:判断当前高级页面状态是开发态或预览态。“true”表示在预览态(即运行态),“false”表示在开发态。
      • StudioToolkit.getCatalogProperties():用于获取当前站点的元数据。

      HttpUtils工具类预置API

      平台内置了HttpUtils工具类,预置API如下:

      • HttpUtils.getCookie:用于获取某个cookie的值。

        代码示例:HttpUtils.getCookie()

      • HttpUtils.setCookie:用于设置cookie的值。

        代码示例:HttpUtils.setCookie("key","value")

      • HttpUtils.getI18n:返回一个Vue18n的实例,配合Vue和VueI18n使用。该Vue18n实例可以在new一个Vue实例时赋值为i18n参数。

        代码示例:HttpUtils.getI18n({locale: HttpUtils.getLocale(), messages: thisObj.getMessages()})

      • HttpUtils.getCsrfToken:通过ajax的方式去调用平台的接口时使用。如果使用平台桥接器的方式,平台会自动在请求header中添加csfr-token头。
        HttpUtils.getCsrfToken(function(csrfToken) {
          $.ajax({
            ….
            headers: {
              CSRF-Token: csrfToken
            },
          })
        })
      • HttpUtils.refreshToken:用于手动刷新页面的accesstoken,通常用在执行退出逻辑时,执行该方法刷新页面的accesstoken。
      • HttpUtils.getUrlParam:用于获取查询字符串中的参数。

        例如某个页面的URL为“https://10.10.10.1:12900/magno/render/cool__app_0000000000NABzEjpNIH/page1?param=1”, 通过执行HttpUtils.getUrlParam("param")返回该参数的值“1”。

      • HttpUtils.getLocalStorage:用于获取某个localStorage的值。

        代码示例:HttpUtils.getLocalStorage("key")

      • HttpUtils.setLocalStorage:用于设置某个localStorage的值。

        代码示例:HttpUtils.setLocalStorage("key","value")

    7. 了解核心逻辑代码。
      • EchartsWidgetTemplate.js
        init()函数:组件初始化入口API,初始化组件通用能力,负责注册组件事件和组件动作。
          /*
           * 组件初始化入口API,初始化组件通用能力,负责注册组件事件和组件动作
           */
          init() {
            this._super.apply(this, arguments); // 组件通用能力构建,调用父类constructor,必须要写
            this.getWidgetI18n().then(() => this.render()); // 渲染组件
          },
        render()函数:组件核心渲染API,负责组件的实例化和数据调用,以及事件和动作的实际实现。
          /**
           * 组件核心渲染api,负责组件的实例化、数据调用及事件、动作的实际实现
           */
          render() {
            const widgetContainer = this.getContainer();
            if (!widgetContainer) return;
            this.initI18n();
            this.initReaderVm(this.getProps(), widgetContainer);
            this.registerWidgetActionAndEvent();
            this.registerResizeEvent(() => this?.readerVm?.echartsInst?.resize());
          },

        beforeDestroy()函数:组件销毁回调事件,负责组件在销毁期间的内存释放逻辑实现,需要把组件绑定的一些dom事件及全局的引用销毁。

          /**
           * 组件销毁回调事件,负责组件在销毁期间的内存释放逻辑实现,需要把组件绑定的一些dom事件及全局的引用销毁
           */
          beforeDestroy() {
            $(window).off('resize');
            this.readerVm && this.readerVm.$destroy && this.readerVm.$destroy();
          },

        initReaderVm()函数:初始化运行态组件VM实例。

          /**
           * 初始化运行态组件VM实例
           * @param {*} props 组件配置项
           * @param {*} widgetContainer 组件容器
           */
          initReaderVm(props, widgetContainer) {
            const { commonProps } = props;
            const thisObj = this;
            thisObj.readerVm = new window.Vue(...)
          },

        registerWidgetActionAndEvent()函数:注册组件对外暴露的事件和动作。

          /**
           * 注册组件对外暴露的的事件和动作
           */
          registerWidgetActionAndEvent() {
            if (!window.Studio) {
              return;
            }
            window.Studio.registerEvents(this, 'clickSeries', { zh_CN: '点击系列', en_US: 'Click Series' });
            window.Studio.registerAction(
              this,
              'highlightSeries',
              { zh_CN: '高亮系列', en_US: 'Highlight Series' },
              [],
              (...args) => this.readerVm.highlightSeries(...args),
            );
          },
      • EchartsWidgetTemplate.ftl
        用于实现DOM结构,示例代码如下所示:
        <div id="EchartsWidgetTemplate" v-cloak>
          <div ref="echartsDom" class="echarts-container"></div>
        </div>
        

  2. 对下载的模板进行重命名,本示例修改为BarGraph。

    1. 进入解压后的目录,修改文件名称,即将EchartsWidgetTemplate.css修改为BarGraph.css,EchartsWidgetTemplate.editor.js修改为BarGraph.editor.js,EchartsWidgetTemplate.ftl修改为BarGraph.ftl,EchartsWidgetTemplate.js修改为BarGraph.js。
      图3 修改后效果
    2. 进入重名后的BarGraph.css文件,将组件ID替换为“BarGraph”,可通过搜索“EchartsWidgetTemplate”关键字进行批量替换。
      图4 修改组件ID
    3. 按照上述操作,替换BarGraph.editor.js、BarGraph.ftl、BarGraph.js和packageinfo.json文件中组件ID。

      如果自定义组件需要在不同的语言环境下使用,messages-zh.json和messages-en.json文件中的“EchartsWidgetTemplate”关键字也请替换为“BarGraph”

  3. 完成上述操作后,将所有文件打成zip包(请直接打包,不要在文件夹外打包),且包名为“BarGraph.zip”

相关文档