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

新建并开发自定义组件

背景信息

当系统预置的组件无法满足用户需求时,用户可自定义组件包进行上传,在页面中进行使用。在开发自定义组件前,请仔细阅读自定义组件开发规范章节内容,了解组件的开发规范。

场景描述

本节以开发网站中常用的标签切换页面为例,向您介绍如何基于组件模板在线开发组件。如图1所示,页面中主要包含标签栏和详情展示两部分,通过切换标签栏来控制详情展示中的内容。

图1 页面示例

在页面开发中,通过两个自定义组件(标签页组件、详情展示组件)实现上述场景,其中标签页组件包含产品类别(手机、笔记本、平板等),详情展示组件用于展示不同产品类别的图片信息。两个组件通过事件和动作机制实现交互,在标签页组件中注册标签切换事件,此事件绑定详情展示组件中切换产品图片的动作。

本节使用的示例组件开发过程中使用了前端开发框架Vue及组件库Element

操作步骤

  1. 下载组件模板。

    1. 参考登录AstroCanvas界面中操作,登录AstroCanvas界面。
    2. 单击页面右上角的“管理”,进入AstroCanvas管理页面。
    3. 在左侧导航栏中,选择“页面资产管理 > 组件模板”。
    4. 系统预置的模板如表1所示,请根据需求选择模板,选中后在模板详情页单击“下载”。
      本章节示例中同时开发标签页组件和详情展示组件,由于本例中组件基于Vue框架实现,所以优先选择widgetVueTemplate模板。
      表1 组件模板列表

      组件模板名称

      功能

      widgetVueTemplate

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

      widgetPropertyTemplate

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

      widgetActionTemplate

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

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

      widgetEventTemplate

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

      widgetBridgeTemplate

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

      widgetPageMacroTemplate

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

    5. 在“下载组件模板”弹出框中,设置标签页组件名称为“TabsWidget”,单击“保存”。同样基于widgetVueTemplate模板下载,设置详情展示组件名称为“DisplayWidget”。

      如果选择“下载原始模板”,下载到本地的包中组件名称不会被修改。

  2. 将下载到本地的Widget包进行解压,认识组件结构。

    本章节以下载的TabsWidget组件为例,说明组件包的文件结构及各文件的功能。

    表2 组件文件结构

    文件名

    文件说明

    TabsWidget.js

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

    TabsWidget.editor.js

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

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

    TabsWidget.css

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

    TabsWidget.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")

  3. 编写TabsWidget组件DOM结构及逻辑。

    1. 在TabsWidget组件包“TabsWidget.js”文件中的render函数下,修改注册的Vue实例。
      示例代码如下所示:
      thisObj.vm = new Vue({
          el: $("#Tabswidget", elem)[0],
          data:{
              activeName: "phone",
              //定义页签栏中的所含项目
              tabs: [
                  {label:"手机",name:"phone"},
                  {label:"笔记本",name:"PC"},
                  {label:"平板",name:"pad"},
                  {label:"智慧屏",name:"HiSilicon"},
                  {label:"穿戴",name:"wearableDevice"}
              ]
          },
          methods:{
              //此函数在切换页签时触发,用于触发后续步骤中TabsWidget组件注册的切换页签事件
              handleClick: function () {
                  thisObj.triggerEvent("switchingTab", {param: this.activeName});
              }
          }
      });
    2. 在TabsWidget组件包“TabsWidget.ftl”文件中,修改DOM结构。
      示例代码如下所示:
      <div id="TabsWidget">
         <!-- 此处用到了Element提供的el-tabs组件  -->
         <el-tabs v-model="activeName" @tab-click="handleClick">
            <el-tab-pane
                    v-for="(tab, index) in tabs"
                    :key="index"
                    :label="tab.label"
                    :name="tab.name"
            ></el-tab-pane>
         </el-tabs>
      </div>

  4. 编写DisplayWidget组件DOM结构及逻辑。

    1. 在DisplayWidget组件包“DisplayWidget.js”文件中的render函数下,修改注册的Vue实例。
      示例代码如下所示:
      thisObj.vm = new Vue({
          el: $("#showtabs", elem)[0],
          data:{
              imgSrc: widgetBasePath + "img/phone.png",
              //定义信息展示组件中展示的图片路径信息
              sources: {
                  phone: widgetBasePath + "img/phone.png",
                  PC: widgetBasePath + "img/PC.png",
                  pad: widgetBasePath + "img/pad.png",
                  HiSilicon: widgetBasePath + "img/hisilicon.png",
                  wearableDevice: widgetBasePath + "img/wearableDevice.png"
              }
          },
          methods:{
              //此方法将在后续步骤中DisplayWidget组件注册的切换展示信息的动作中调用
              switchPic: function (param) {
                  this.imgSrc = this.sources[param];
              }
          }
      });
      • 上述代码中定义的展示图片文件可单击img.zip获取,下载后解压到DisplayWidget目录中即可正常使用。
      • 本段示例代码中widgetBasePath变量为组件包上传后的路径,在组件模板中已包含获取此变量的逻辑,在此直接使用即可(此例也展示了组件中如何引入本地图片的基本方法)。
    2. 在DisplayWidget组件包DisplayWidget.ftl文件中实现DOM结构。
      示例代码如下所示:
      <div id="showTabs">
         <img :src="imgSrc">
      </div>

  5. 注册、实现事件和动作。

    1. TabsWidget组件包“TabsWidget.js”文件中的init函数中注册页签切换的事件
      示例代码如下所示:
      if((typeof(Studio) != "undefined") && Studio)
      {
          var sendEventConfig = [{
              "name": "param"
          }];
          Studio.registerEvents(
              thisObj,
              "switchingTab",
              {"zh_CN": "切换标签", "en_US": "Switching Tab"},
              sendEventConfig
          );
      }
    2. DisplayWidget组件包“DisplayWidget.js”文件中的init函数中注册切换展示图片的动作
      示例代码如下所示:
      if((typeof(Studio) != "undefined") && Studio)
      {
          var receiveActionConfig = {
              "name": "param"
          };
          Studio.registerAction(
              thisObj,
              "switchingPicture",
              {"zh_CN": "切换图片", "en_US": "Switching Picture"},
              receiveActionConfig,
              $.proxy(thisObj.switchingPicture, thisObj),
          );
      }

      DisplayWidget组件包“DisplayWidget.js”文件中的组件示例中(即与init和render方法在同级作用域)实现上述注册的动作,示例代码如下所示:

      switchingPicture: function (event) {
          if (event && event.eventParam) {
              this.vm.switchPic(event.eventParam.param);
          }
      }

      “DisplayWidget.js”文件中第一行代码“var DisplayWidget = StudioWidgetWrapper.extend();”,其含义为新建的自定义组件继承于AstroZero平台定义的StudioWidgetWrapper类,此为开发规范,基于此类开发的自定义组件可以使用平台提供的如下方法:

      • var widgetProperties = thisObj.getProperties(); :获取组件的自定义属性配置值。
      • var elem = thisObj.getContainer(); :获取组件的DOM元素。
      • var connectorProperties = thisObj.getConnectorProperties(); :获取组件的桥接器属性配置值。

  6. 定义组件依赖库及组件在绝对布局中默认尺寸。

    本节开发的示例组件TabsWidget依赖Vue和Element库,DisplayWidget依赖Vue库。所依赖的Vue库已在之前选择的组件模板“widgetVueTemplate”中定义,这里只需要在TabsWidget组件包的packageinfo.json文件中定义所依赖的Element库即可。

    1. 查询AstroCanvas预置库信息,本例以查询库“Element”为例。

      在AstroCanvas界面我的资产 > 我的库中,搜索所需库“Element”,单击,查看库ID和版本号信息。

      本例中查询的Element库ID为“global_Element”,库最新版本号为“101.0.8”。

      图2 查看库详情
      图3 查看库ID和版本
    2. 修改TabsWidget组件包中“packageinfo.json”文件的requires、width、height属性。
      示例代码如下所示:
      "requires": [
          {
            "name": "global_Vue",
            "version": "100.7"
          },
          {
            "name": "global_Element",
            "version": "101.0.8"
          }
      ],
      "width": "900",
      "height": "55",
    3. DisplayWidget组件只依赖Vue库,且在下载时选择的widgetVueTemplate组件模板,所依赖的Vue库已在模板中定义,本例无需修改,只需修改width、height属性。
      示例代码如下所示:
      "width": "900",
      "height": "560",

  7. 将组件的全部文件重新打成zip包(请直接打包,不要在文件夹外打包)。
分享:

    相关文档

    相关产品