# 自定义 UI *(Beta)
在 USV 0.4, 提供了自定义 UI 的能力
# React
基于 uCode
内置了 React 16.14.0, 因此我们首先实现了 React 组件的集成.
# 环境准备
# 1. 脚手架 集成
最快的方式是, 直接使用我们最新的脚手架:
❯ npx @ubtech/create-ucode-extension
uCode v4 插件脚手架 v1.3.0
_|_|_| _|
_| _| _| _|_| _|_|_| _|_|
_| _| _| _| _| _| _| _|_|_|_|
_| _| _| _| _| _| _| _|
_|_|_| _|_|_| _|_| _|_|_| _|_|_|
? 请输入插件的名字 ui-test
? 要集成的特性 (Press <space> to select, <a> to toggle all, <i> to invert selection, and <enter> to proceed)
◯ 串口协议 SerialPort
◯ 蓝牙协议 Ble
◯ UDP/TCP协议 UDP/TCP
◯ 烧录模式
❯◯ 自定义 UI 组件 *(Beta)
里面已经集成了, 自定义 UI 组件的案例
# 3. 如果你想自行添加, 可以按照以下操作:
- 添加以下依赖:
- @types/react: 16.14.0
- @babel/preset-react
可以用这个指令添加:
注意版本号
由于 React 每个版本的特性不太一样, 建议你严格按照上述的版本号安装, 否则 TypeScript 的类型校验可能会报错
- 修改 babel 配置
找到
babel.config.js
需要在
presets
新增一条:'@babel/preset-react'
如果是 TypeScript 的版本, 看起来如下:
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
'@babel/preset-react',
],
};
- 修改 webpack 配置
- 找到
webpack.common.js
- 找到
module.rules
确保 babel-loader
的文件处理有包括 jsx
或者 tsx
如下, 第二行高亮所示:
{
test: /\.(js|ts|jsx|tsx)$/,
exclude: /node_modules/,
include: [path.join(__dirname, 'src')],
use: ['babel-loader'],
}
- 找到
resolve.extensions
需要增加新的文件处理后缀, 如下所示:
resolve: {
extensions: ['.js', '.ts', '.jsx', '.tsx'],
alias: {},
fallback: {
stream: require.resolve('stream-browserify'),
crypto: require.resolve('crypto-browserify'),
os: require.resolve('os-browserify/browser'),
},
}
- 找到
externals
由于 uCode 已经内置了 React 框架, 这里打包的时候不需要集成 React
需要添加 react
, 如下
externals: {
'@ubtech/ucode-extension-common-sdk': 'UCodeExtensionCommonSDK',
react: 'React',
},
- 如果是 TypeScript 需要打开
JSX
的支持
- 找到 tsconfig.json
- 添加如下配置:
"jsx": "react"
# 添加组件
# 新增一个 React 组件 (Hook 组件)
我们目前只支持 Hook 组件, Class 组件目前还未提供, 后续会添加上
以 TypeScript 版本为例子, 下面是一个 example.tsx
的案例
import React from 'react';
import { UCodeExternalHardwareDefinition } from '@ubtech/ucode-extension-common-sdk/types';
export const DemoComp: UCodeExternalHardwareDefinition.ReactComponent = (props) => {
console.log(props.getDevice());
return (
<>
<h1>
我是一个 React Hook 组件 MenuId: {props.menuId}, 设备类型: {props.getDevice()?.deviceType?.name}
</h1>
</>
);
};
我们预设了一个 组件类型, props 里面注入了, getDevice()
等方法, 你可以在这里直接使用设备连接实例
# 注册设备设置菜单
组件需要挂载在设置菜单里面, 因此我们要注册设置菜单
- 找到
index.ts
- 找到
self.UCode.extensions.register
添加以下代码:
SettingMenuRegister
就是用于注册 设置菜单的, 更多详细的内容, 可以参照 设置菜单的文档
DemoComp
就是我们刚刚创建的 React 组件
additionalData
可以定制更多参数, 目前有 title
, size
, 后续会增加更多的参数
import { DemoComp } from './components/example';
...
...
self.UCode.extensions.register({
DeviceRegister: [spRegister, bleRegister, WebsocketRegister],
BlockRegister: ExampleDeviceExtension,
UploadModeRegister,
SettingMenuRegister: {
myMenu: {
name: '我的组件',
icon: '',
type: 'component',
component: DemoComp,
additionalData: {
title: '我的组件',
},
},
},
});
组件使用
我们目前只提供了, 在设置菜单里面使用 自定义 组件
# 使用组件
我们来看看实际效果
- 点击硬件菜单
点击刚刚注册的
我的组件
可以看到我们刚刚新增的组件
# CSS, 图片资源等处理
当前文档, 暂未提供
可以使用 url-loader, css-loader 先自行处理
# 限制
- 自定义组件, 目前只能在, 设备设置菜单里面使用, 而且为了防止滥用和保证用户体验, 所有的组件的打开和关闭, 都是由用户行为控制
- 目前组件, 没法复用, 也就是每个菜单组件用的都是一个独立组件
- 不支持懒加载, 动态加载
- 目前支持 React 组件, 暂不支持 其他框架, 或者原生渲染
- React 组件目前只支持 Hook 类型的组件
- 用户点击关闭按钮, 会销毁组件, 目前暂时无法提供后台运行