轻应用支持使用系统提供的标准组件搭建页面,并支持通过JSX编写简单的代码,但有复杂交互的页面还是难以通过搭建实现。因此平台提供了自定义页面功能,您可以在IDE中使用React开发页面并打包上传到系统中,自定义页面将和系统标准页面一样展示在菜单中。本文介绍如何开发和管理自定义页面。
背景信息
由于在React中没有页面的概念,只有组件的概念,因此会通过配置文件将React的组件映射到系统的页面。BizWorks的前端使用的是React框架,因此自定义页面暂时也只支持通过React编写。
开发自定义页面流程说明
使用流程说明如下:
-
下载开发模板:平台提供了一个自定义页面的开发模板,用户可以下载后在模板上修改并开发自己的页面。
-
开发React组件:用户在线下通过IDE开发自定义页面。
-
导出组件:将开发的React组件导出,用于后续配置组件和页面Id的映射关系。
-
配置React组件和页面Id映射关系:在代码中定义页面Id和导出的组件映射关系。
-
本地调试:您可以在本地调试页面,但暂不支持调用平台提供的API方法。
-
工程打包:在线下将工程打成zip包。
-
上传zip包文件到自定义页面:系统中的一条自定义页面数据对应的是一个zip包,而一个zip包中又可以包含多个自定义页面。
-
创建页面:创建页面,指定为全代码类型,并关联到特定的页面Id。
-
创建菜单:创建菜单的步骤和为普通编排页面创建菜单以及菜单配置相同。
-
部署轻应用:完成上述配置后需要重新部署轻应用。
相关对象间的关系如下图。
对象间关系的相关说明如下。
-
一个轻应用中可以包括多个自定义页面的数据,每条自定义页面数据中可以上传一个React工程打包后的zip文件。
-
每个zip包中可以包括多个React组件。
-
通过配置文件可以将一个React组件映射到多个自定义页面。
-
一个轻应用中可以在页面编排页中创建多个页面。
-
每个全代码类型的页面可以一一映射到代码中定义的页面。
开发自定义页面操作步骤
步骤一:下载开发模板
关于如何下载开发模板,请参见下载示例代码。
步骤二:开发React组件
请按正常流程开发页面,示例代码如下。
import React from "react";
import { CustomPageProps } from "../../types";
import "./index.scss";
type ComponentState = {
customFunctionResult: any[];
};
export default class PageOne extends React.Component<CustomPageProps, ComponentState> {
constructor(props: CustomPageProps) {
super(props);
this.state = {
customFunctionResult: [],
};
}
render() {
const animaComponent: React.ReactNode = <img className="img1" src={require("../../public/dog.jpg")} />;
const url = new URL(location.href);
const background = url.searchParams.get("background");
return (
<div>
<div
className="pageOneContainer"
style={{
background: background || "",
}}>
宠物店一号
{animaComponent}
<button
onClick={() => {
const { invokeFunction } = this.props?.utils?.my;
// ...
}}>
</button>
</div>
</div>
);
}
}
步骤三:导出组件
import "./public-path";
import React from "react";
import ReactDOM from "react-dom";
import { Router } from "react-router-dom";
import { SubAppProps } from "./types";
import { getComponentByPageId } from "./utils";
import getPageList from "./pages/getPageList";
export async function mount(props: SubAppProps) {
const { history, utils, pageId, container } = props;
const Component = getComponentByPageId(pageId);
const app: React.ReactNode = Component && <Component pageId={pageId} utils={utils} />;
ReactDOM.render(React.createElement(Router, { history }, [app]), container);
}
export async function unmount(props: SubAppProps) {
const { container } = props;
container && ReactDOM.unmountComponentAtNode(container);
}
export const pageList = getPageList();
-
加载页面时系统会运行mount方法。
-
卸载页面时系统会运行unmount方法。
-
pageList是文件中包含的页面列表。
步骤四:配置getPageList.ts和getPageMap.ts文件
配置getPageList.ts和getPageMap.ts文件,以及配置文件和自定义页面编码的映射关系。其中:
-
getPageList.ts文件定义了整个自定义页面项目包含的自定义页面编码。
-
getPageMap.ts文件定义了自定义文件编码和React组件文件中定义的页面间的映射关系。
export default function () {
return [
{
pageId: "MyFirstCustomPage_lc",
},
{
pageId: "fullcodetest2",
},
{
pageId: "fullcodetest3",
},
]
} import PageOne from "./pageOne";
import PageTwo from "./pageTwo";
export default function () {
return {
MyFirstCustomPage_lc: PageOne,
fullcodetest2: PageTwo,
fullcodetest3: PageOne,
};
}
步骤五:本地调试
在工程根目录,运行npm start,把启动后日志里的URL粘贴到运行态地址栏后,进行调试操作。
步骤六:打包工程
完成开发后,您可以通过npm run build命令,将工程打成zip包。
系统默认将创建名称为dist的目录,并在该目录下创建名称为customJsCode的zip包。
dist/
├── customJsCode.zip
└── subApp.js
步骤七:上传zip包文件到自定义页面(新增自定义页面)
-
登录BizWorks,在选择平台下拉列表中选中轻应用组装平台。

单击页面右上角
图标或其文本框区域,在下拉列表中单击目标项目名称后,单击应用页签。在应用列表页面单击目标轻应用名称。
在目标轻应用导航栏中,单击扩展管理,在扩展管理页面单击自定义页面页签。
-
在扩展管理的自定义页面页签,单击新增自定义页面。
-
在新增自定义页面面板,单击虚线框区域或拖拽文件至虚线框区域内,完成文件上传。文件大小不超过50MB。
-
填写自定义页面名称、编码和描述(可选)。
-
单击确认。
在自定义页面页面,您可查看所新增的定义页面。
步骤八:创建页面
在目标轻应用导航栏中,选择。
-
在页面编排页面,单击新建页面。
-
在新建页面面板,完成以下配置项设置后,单击创建。参数包括页面名称和描述(可选),按需勾选显示导航菜单和需要登录。
说明-
编码需填写为步骤四中config.json文件中定义的pageId。
-
开发模式需选择为前端全代码。
更多参数信息,请参见参数说明。
-
步骤九:创建菜单并添加菜单项到导航
-
后续创建菜单项并指向该页面,将菜单项添加到菜单配置中,然后部署轻应用的流程与普通页面相同,不再赘述。
在目标轻应用导航栏中,选择。在页面编排页面,单击导航与框架配置。
-
在菜单管理页面的菜单项页签,单击新增菜单项。
-
在新增菜单项对话框中,完成参数配置后,单击确定。参数包括菜单名称、唯一标识(保存后不可更改)和描述。
说明菜单指向类型需选择为应用内页面,目标页面选择为您所需的目标自定义页面名称。更多信息,请参见新增和管理菜单项。
-
添加菜单项到导航。具体操作,请参见新增和管理菜单配置。
步骤十:部署轻应用
部署轻应用。具体操作,请参见部署和管理轻应用。
开发说明
在开发React组件时,您可以使用以下Props,并且使用样式时要遵循以下规范。
组件Props
开发自定义组件时,可以获取系统传入的两个Props组件:
-
queryParam:是一个object类型的数据,格式如下。
{ //应用编码 "applicationCode": "xxx", //页面编码 "pageId": "xxx", //当前选中的菜单唯一标识,不是系统中设置的菜单编码,不常用 "selectedKey": "xxx" } -
utils:主要用来提供常用的API。关于这些API的使用方式,请参见JS API。
样式
为了防止不同样式文件的类名发生冲突,对于在规则文件中设置了运行态所生成的类名,系统默认会在用户定义的类名后加上一定长度的hash值,具体配置如下。
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: 'babel-loader',
exclude: /node_modules/
},
{
test: /\.ts(x)?$/,
loader: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 1,
modules: {
localIdentName: "[local]--[hash:base64:5]",
}
}
}
]
},
]
}
};
在写样式类时您可以使用如下方式。
import React, { Component } from 'react'
import styles from './targetPage.css'
export default class TargetPage extends Component {
goBack = () => {
const {goBack} = this.props.utils.my.router
goBack()
}
render() {
return (
<div>
<h2>这是一个跳转后的目标页面</h2>
<button className={styles.btn} onClick={this.goBack}>返回上一页</button>
</div>
)
}
}
JS API
在开发React组件时,您可以使用以下JS API。
API列表
|
序号 |
API |
使用说明 |
|
1 |
utils.my.alert() |
显示警告弹窗 |
|
2 |
utils.my.confirm() |
显示弹窗 |
|
3 |
utils.my.error() |
显示错误信息 |
|
4 |
utils.my.loading() |
显示加载信息 |
|
5 |
utils.my.success() |
显示成功信息 |
|
6 |
utils.my.showMessage() |
显示信息,可以指定信息类型 |
|
7 |
utils.my.getVariableValue() |
获取变量 |
|
8 |
utils.my.setVariableValue() |
设置变量 |
|
9 |
utils.my.invokeFunction() |
调用后端服务方法 |
|
10 |
utils.my.callJsFunction() |
调用JS方法 |
|
11 |
utils.my.log() |
打印控制台日志 |
|
12 |
utils.my.router.getLocationUri() |
获取页面URI |
|
13 |
utils.my.router.getUrlQuery() |
获取查询参数 |
|
14 |
utils.my.router.goBack() |
返回上一页 |
|
15 |
utils.my.router.openLink() |
打开指定链接 |
|
16 |
utils.my.router.openPage() |
跳转应用内其他页面 |
使用示例
调用API示例如下。
/**
* 调用后端服务方法
* @param 后端服务方法编码
* @param 服务方法入参,所有参数放在一个对象中传入
*/
this.my.invokeFunction("functionCode", {})
/**
* 快捷调用警告对话框
* @param
* https://fusion.alibaba-inc.com/pc/component/dialog?themeid=40463#Dialog%20Alert%20Config%20Dialog%20Confirm%20Config
*/
this.my.alert({
content: "",
onOk: () => { },
});
/**
* 快捷调用确认对话框
* @param 同Fusion组件的config配置
* https://fusion.alibaba-inc.com/pc/component/dialog?themeid=40463#Dialog%20Alert%20Config%20Dialog%20Confirm%20Config
*/
this.my.confirm({
content: "",
onOk: () => { },
onCancel: () => { },
});
/**
* 快捷调用消息弹窗
* @param 同Fusion组件的config配置
* https://fusion.alibaba-inc.com/pc/component/message?themeid=40463#Message%20Show
*/
this.my.showMessage({
type: 'error',
title: '错误',
content: '请联系相关人员反馈!',
duration: 0, // 永远存在
hasMask: true
});
/**
* 快捷调用成功消息弹窗
* @param 同Fusion组件的config配置
* https://fusion.alibaba-inc.com/pc/component/message?themeid=40463#Message%20Success%20Error%20Notice%20Help%20Loading
*/
this.my.success("demo");
/**
* 快捷调用错误消息弹窗
* @param 同Fusion组件的config配置
* https://fusion.alibaba-inc.com/pc/component/message?themeid=40463#Message%20Success%20Error%20Notice%20Help%20Loading
*/
this.my.error("demo");
/**
* 快捷调用加载消息弹窗
* @param 同Fusion组件的config配置
* https://fusion.alibaba-inc.com/pc/component/message?themeid=40463#Message%20Success%20Error%20Notice%20Help%20Loading
*/
this.my.loading("demo");
/**
* 打开外部链接
* @param 外部链接地址
* @param 外部链接地址的queryString
* @param "self"代表在当前标签页下打开新页面,否则表示打开新的标签页
*/
this.my.router.openLink("http://www.example.com/a=hello", { a: "world", b: "hello" } "self");
/**
* push方法的封装版本,打开appPage内部页面
* @param pageId
* @param 内部页面参数
*/
this.my.router.openPage("pageId", {});
/**
* 获取当前的Url对象
*/
this.my.router.getLocationUri();
/**
* getLocationUri的封装版本,直接获取当前查询字符串的Map
*/
this.my.router.getUrlQuery();
/**
* 回退到上一个内部页面,等同于点击浏览器左上角退后按钮
*/
this.my.router.goBack();
/**
* 获取变量
* @param 变量名
*/
this.my.getVariableValue("varName");
/**
* 设置变量
* @param 变量名
* @param 变量值
*/
this.my.setVariableValue("varName", 1234);
/**
* 裸调ajax
* @param 请求地址
* @param 请求配置,同Axios Request Config
* https://github.com/axios/axios#request-config
*/
this.my.request("/lightAppEngine/metadata/navigation/getNavigation/v1", {method: "post", data: {applicationCode: "qing10"}}).then(res=>console.log(res))
/**
* 对request的post封装
* @param 请求地址
* @param Request Body
* @param 请求配置,同Axios Request Config
* https://github.com/axios/axios#request-config
*/
this.my.post(url, data?, config?)
/**
* 对request的get封装
* @param 请求地址
* @param Query String
* @param 请求配置,同Axios Request Config
* https://github.com/axios/axios#request-config
*/
this.my.get(url, params?, config?)
编辑自定义页面
-
在自定义页面页面,单击目标自定义页面或目标自定义页面右侧操作列下的编辑。
-
在编辑自定义页面面板,完成自定义页面名称和描述信息修改后,单击确认。
下载自定义页面
在自定义页面页面,单击目标自定义页面名称右侧操作列下的下载。
删除自定义页面
-
在自定义页面页面,单击目标自定义页面名称右侧操作列下的删除。
-
在二次确认对话框中,单击删除。
下载示例代码
在自定义页面页面,单击下载示例代码。