基于 Zion 平台现有能力之上,通过编写 React 组件代码的方式扩展自定义组件的能力,如动态表单与即时验证、数据驱动的图表、复杂动画与过渡效果、交互式地图与数据可视化等。 点击查看 B 站教学视频
先决条件
用户对 FunctorZ 平台有一定了解和实践,同时拥有一定的前端知识,拥有一定的 TypeScript 知识,并能够自己编写符合自己业务需求的 React 组件代码。
对 React 感兴趣,请参考免费教学视频与文档:React 从入门到项目实战教程,React 官方中文文档
开始使用
如果有使用初期版本的代码组件(初期也被成为自定义组件)的项目,请尽快参考本文新建项目成为最新的代码组件。
我们推荐使用 node 18 或者 20 版本。目前请暂勿使用最新的 node 22,以免出现一些意料之外的问题。
安装全局命令行工具。
> npm i -g functorz
# 注意如果因为网络原因安装缓慢或卡主,可参考添加如下后缀,改变npm源并强制重新安装。
# npm i -g functorz --registry=https://registry.npmmirror.com --force
操作概览
安装后,运行 functorz --help,可以查看全部命令及解释。
> functorz --help
zvm cli 0.4.7
Usage: functorz [options] [command]
Options:
-h, --help display help for command
Commands:
create [options] <项目名> 初始化项目。会在登录的账户下创建关联的自定义组件项目,并且在本地初始化一个模板项目。
publish [options] 发布项目。
reinit [options] 重新注册项目ID,将本地项目重新发布为自己账号下的一个新项目。
reset [options] 创建模板项目。在当前目录下重置一个模板项目。
signin [options] <用户名/邮箱> <密码> 登录到Zion平台,目前仅支持用户名密码/邮箱密码方式登录。
signout [options] 退出,删除目前登录信息。
help [command] display help for command
登录平台
在自己的工作目录下运行如下命令。
> functorz signin 你的邮箱账号 你的密码
等待命令执行完成。
> functorz signin 你的邮箱账号 你的密码
zvm cli 0.4.7
ℹ 登录
✔ 登录成功
创建项目
在工作目录继续运行如下命令。
# create 项目名
> functorz create test
等待命令执行完成。该步命令会创建一个模板项目,并且在平台上注册一个代码组件项目。
一个代码组件项目中可以包含多个代码组件。
注意此时还没有发布任何版本。
> functorz create test
zvm cli 0.4.7
ℹ 项目初始化
✔ 准备工作目录完成
✔ 获取最新模板完成
✔ 生成项目完成
✔ 在Zion平台注册项目完成
✔ 关联远程项目完成
✔ 项目初始化完成
编辑代码
到代码组件项目目录中,安装依赖。
> cd test
> npm install
一个典型的代码组件库项目的基本结构如下所示。
.
├── codegen.ts
├── index.html
├── package-lock.json
├── package.json
├── public
│ └── vite.svg
├── src
│ ├── App.scss
│ ├── App.tsx
│ ├── components
│ │ ├── AddCalculator
│ │ │ ├── AddCalculator.tsx
│ │ │ └── index.ts
│ │ ├── Bar3DChart
│ │ │ ├── Bar3DChart.tsx
│ │ │ ├── db.ts
│ │ │ ├── index.ts
│ │ │ ├── options.tsx
│ │ │ └── processData.ts
│ │ ├── ConfirmModal
│ │ │ ├── ConfirmModal.tsx
│ │ │ └── index.ts
│ │ ├── DataTable
│ │ │ ├── DataTable.tsx
│ │ │ └── index.ts
│ │ ├── DemoChart
│ │ │ ├── DemoChart.tsx
│ │ │ ├── index.ts
│ │ │ └── options.tsx
│ │ └── index.ts
│ ├── graphql
│ │ └── accountListQuery.gql
│ ├── index.css
│ ├── main.tsx
│ ├── typings
│ │ ├── global.d.ts
│ │ └── graphql.d.ts
│ └── vite-env.d.ts
├── tree.txt
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
└── zvm-temp
其中 src/components 是声明和编辑代码组件主要目录。
每个自定义组件必须符合下述规则。
- 组件必须有一个目录在 src/components 下,该目录名称必须为组件名,该目录下必须至少包含 index.ts 和 组件名.tsx。其中 index.ts 用于导出组件,组件名.tsx 用于编写业务逻辑。
src/components/组件名/组件名.tsx 下声明的组件的属性类型声明必须 export 4 个 interface,分别是 [${组件名}PropData], [${组件名}StateData],[${组件名}Event],以及 [${组件名}Prop]。且该 4 个 interface 符合如下约定。
- [${组件名}PropData] 用于声明从外部宿主项目需要传入的数据,目前支持的类型包括 string, number, boolean。
- [${组件名}StateData] 用于声明从代码组件内部暴露给外部宿主项目的状态,其类型必须为 State
,其中 State 需要从 zvm-code-context 包中引入。 - [${组件名}Event] 用于声明代码组件内部除外外部的事件,其属性的类型必须为 EventHandler。EventHandler 需要从 zvm-code-context 包中引入。
[${组件名}Prop] 固定包含上述 3 个类型的属性,且名称分别 propData, propState 和 event。
import { ExclamationCircleFilled } from '@ant-design/icons'; import { Button, Modal } from 'antd'; import { EventHandler } from 'zvm-code-context'; // 暴露宿主项目上下文的包,里面还暴露了一个很重要的 API,useAppContext,具体可参考模板项目和下文。 // 组件的属性数据,右边栏配置,由外向内传递。这里暴露了三个右边栏的数据配置项,分别是 buttonTitle、modalTitle、modalContent。 export interface ConfirmModalPropData { buttonTitle: string; modalTitle: string; modalContent?: string; } // 组件的状态,右边栏配置,由内向外传递,可供宿主项目的其他组件绑定。 export interface ConfirmModalStateData {} // 组件可供绑定的事件,类型目前是固定的,只能是 EventHandler。 export interface ConfirmModalEvent { onConfirm?: EventHandler; onCancel?: EventHandler; } // 固定写法。运行时,宿主项目将通过以下三个属性传递进来。 export interface ConfirmModalProps { propData: ConfirmModalPropData; propState: ConfirmModalStateData; event: ConfirmModalEvent; } // 组件逻辑。 export function ConfirmModal({ propData, event }: ConfirmModalProps) { // 确认的事件逻辑。 const showConfirm = () => { Modal.confirm({ title: propData.modalTitle || '', // 绑定宿主项目传进来的弹窗标题内容。 icon: <ExclamationCircleFilled />, content: propData.modalContent || '', // 绑定宿主项目传进来的弹窗主内容。 onOk() { event.onConfirm?.call(null); // 调用宿主项目绑定的确认事件处理逻辑。 }, onCancel() { event.onCancel?.call(null); // 调用宿主项目绑定的取消事件处理逻辑。 }, }); }; return ( <Button type='primary' onClick={showConfirm}> {propData.buttonTitle || ''} // 绑定宿主项目的按钮文本内容。 </Button> ); }
在 src/components/index.ts 中暴露新编辑的组件。
可以参考模板项目中的示例代码。 请严格遵循上述约定,否则不保证能够正确识别相关组件和对应的声明。
相关 API
zvm-code-context 为代码组件提供了一些对宿主项目上下文绑定过的 API。开发者可以通过相关 API 更便捷地实现所需功能。
// 某组件内
import { useAppContext } from 'zvm-code-context';
const { component, discover, query, navigate, globalData, pageData } =
useAppContext();
// ...
- component,内包含了宿主项目用于描述当前组件实例的所有数据信息。
- discover(id: string): Component,用于根据一个组件 ID 获取宿主项目中的特定组件实例。
- query 用于向宿主项目的后端发起一个请求。具体可参考模板项目中的 DataTable 组件。
- navigate 用户跳转到宿主项目的制定页面。我们推荐用这种方式跳转,以执行一些特定的跳转逻辑。
- globalData 中拥有当前宿主项目的全局数据。
- pageData 中拥有当前宿主项目的当前运行页面的页面数据。
发布项目
- 编辑 package.json 中的 version。代码组件的 version 严格遵循 npm 包的规范。
- 运行如下命令发布项目。
# 必须在项目的目录下运行
> functorz publish
zvm cli 0.4.7
ℹ 发布项目
✔ 扫描组件信息完成
✔ 组件解析完成
✔ 项目构建完成
✔ 注册版本信息中0.0.2
ℹ 产物上传开始
ℹ ConfirmModal-DkZp9JXU.js
ℹ __federation_expose_Main-DxfqaaDF.js
ℹ __federation_fn_import-lyDSGtOx.js
ℹ __federation_shared_classnames-DNBU_3PZ.js
ℹ __federation_shared_constate-BXZUjDp9.js
ℹ __federation_shared_lodash-CMjxsLue.js
ℹ __federation_shared_moment-CEY8C7XE.js
ℹ __federation_shared_react-DO25RkNm.js
ℹ __federation_shared_react-dom-ChyTJqHm.js
ℹ __federation_shared_react-router-dom-BwChNopu.js
ℹ __federation_shared_zvm-code-context-DJ2L4k_6.js
ℹ _commonjsHelpers-BFTU3MAI.js
ℹ index-BBIatVb0.js
ℹ remoteEntry.js
ℹ style-CLbg9otl.css
✔ 产物上传完成
✔ 发布项目成功
发布成功,此时可以前往平台的任意无代码项目中的左边栏配置新发布的代码组件库。
如果发布失败,可以运行 functorz publish --verbose
,以获得更详细的信息,在社区或者用户群众提报错误。
导入代码组件
在任意无代码项目中,左边栏点击对应图标,在弹窗中找到刚发布的代码组件项目,并勾选。
此时左边栏最下方新增新发布的代码组件。
右边栏的数据配置和事件配置,是完全根据自己编写的代码而生成。必须注意,代码中的声明一定要按照规范编写,否则无法生成右边栏配置。
同步数据库
新配置或更改代码组件项目后,一定要同步数据库或者预发布才能在运行时正常使用。点击左上角对应图标按钮。
配置代码组件属性
配置的属性根据编辑代码时声明的属性类型解析而成,所以一定要严格遵守约定。