# 自定义 UI *(Beta)

在 USV 0.4, 提供了自定义 UI 的能力

# React

基于 uCode 内置了 React 16.14.0, 因此我们首先实现了 React 组件的集成.

react logo

# 环境准备

# 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. 如果你想自行添加, 可以按照以下操作:

  1. 添加以下依赖:
  • @types/react: 16.14.0
  • @babel/preset-react

可以用这个指令添加:

注意版本号

由于 React 每个版本的特性不太一样, 建议你严格按照上述的版本号安装, 否则 TypeScript 的类型校验可能会报错

  1. 修改 babel 配置
  • 找到 babel.config.js

  • 需要在 presets 新增一条: '@babel/preset-react'

如果是 TypeScript 的版本, 看起来如下:





 



module.exports = {
  presets: [
    '@babel/preset-env',
    '@babel/preset-typescript',
    '@babel/preset-react',
  ],
};
  1. 修改 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',
  },
  1. 如果是 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: '我的组件',
      },
    },
  },
});

组件使用

我们目前只提供了, 在设置菜单里面使用 自定义 组件

# 使用组件

我们来看看实际效果

  1. 点击硬件菜单

设置菜单

  1. 点击刚刚注册的 我的组件

  2. 可以看到我们刚刚新增的组件

我的组件

# CSS, 图片资源等处理

当前文档, 暂未提供

可以使用 url-loader, css-loader 先自行处理

# 限制

  • 自定义组件, 目前只能在, 设备设置菜单里面使用, 而且为了防止滥用和保证用户体验, 所有的组件的打开和关闭, 都是由用户行为控制
  • 目前组件, 没法复用, 也就是每个菜单组件用的都是一个独立组件
  • 不支持懒加载, 动态加载
  • 目前支持 React 组件, 暂不支持 其他框架, 或者原生渲染
  • React 组件目前只支持 Hook 类型的组件
  • 用户点击关闭按钮, 会销毁组件, 目前暂时无法提供后台运行