WorkshopFramework
[TOC]
安装
使用 npm 或 yarn 安装
npm install workshop-framework --registry http://repository.aishu.cn:8081/repository/npm-all/
yarn add workshop-framework --registry http://repository.aishu.cn:8081/repository/npm-all/
示例
import './polyfill'
import React, { lazy, Suspense } from 'react'
import { FrameWork } from 'workshop-framework'
import './global.css'
const AsyncComponent = (asyncComponent) => {
const Component = lazy(() => asyncComponent)
return (props) => (
<Suspense fallback={<></>}><Component {...props} /></Suspense>
)
}
const menusItems = [
{
label: '组织管理',
key: 'management',
icon: <CiOutlined />,
children: [
{
label: '用户组织管理',
key: 'usermanagement',
children: [
{
label: '用户组织管理-1',
key: 'me',
path: '/home/me',
app: {
name: 'first',
entry: 'http://localhost:1007',
},
},
{
label: '用户组织管理-2',
key: 'role',
path: '/home/role',
app: AsyncComponent(import('./components/Demo1')),
}
]
}
]
},
]
const config = {
appProps: {
language: 'zh-cn',
},
nav: {
logo: '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',
theme: 'red',
customStyle: false,
account: {
name: 'admin',
items: [
{
label: '语言',
key: 'language',
children: [
{
label: '简体中文',
key: 'zh-cn',
},
{
label: '繁体中文',
key: 'zh-tw',
},
{
label: 'English',
key: 'en-us',
}
],
defaultSelectedKeys: ['en-us'],
},
{
label: '退出',
key: 'logout',
},
],
onClick: (keys) => {
},
},
extraElements: [
{
icon: <CiOutlined />,
label: '部署控制台',
key: 'cluster',
onClick: (key) => {
},
float: 'right',
},
{
icon: <CiOutlined />,
label: '管理控制台',
key: 'console',
float: 'left',
},
],
menu: {
items: menusItems,
defaultCollapsed: localStorage.getItem('menuCollapsed') === 'true',
defaultMenuWidth: localStorage.getItem('menuWidth') ? parseInt(localStorage.getItem('menuWidth')) : undefined,
onPathChange: ({ path, isPathExist, keys }) => console.log(path, isPathExist, keys),
onMenuWidthChange: (width) => localStorage.setItem('menuWidth', width),
onCollapsedChange: (collapsed) => localStorage.setItem('menuCollapsed', collapsed)
},
locale: 'zh-ch',
},
}
ReactDOM.render(<FrameWork config={config}/>, mountNode)
使用微前端时,需导入polyfill,兼容ie11
polyfill.ts
import 'whatwg-fetch'
import 'custom-event-polyfill'
import 'core-js'
引入样式
global.css
@global-import 'workshop-framework/dist/workshop-framework.umd.min.css'
组件
1、FrameWork
工作台插件框架
API
FrameWorkPropsType
| config | 配置信息 | Config | - |
| customNavigate | 自定义navigate方法 | (path: string) => void | - |
| onGetNavigate | 获取navigate方法 | (navigate: NavigateFunction) => void | - |
Config:
| nav | 顶栏、菜单等信息 | Nav | - |
| appProps | 内容页(子应用 or 主应用的组件)的信息,所有的内容页均会继承 | Record<string, any> | {} |
| microfrontedConfiguration | 微应用的配置信息 | Record<string, any> | {} |
| microfrontedLoadingMode | 微应用的加载模式 | router | manual | none | router |
Nav:
| logo | base64的logo,不可和logoSrc、logoElement同时存在 | string | - |
| logoSrc | logo图片的src,不可同时存在 | string | - |
| logoElement | logo元素,不可同时存在 | React.ReactElement | - |
| theme | 主题色 | string | #126EE3 |
| customStyle | 是否自定义主题色 | boolean | false |
| themeMode | 主题模式 | dark | light | dark |
| headBarStyle | 顶栏的样式 | Record<string,any> | - |
| account | 账号信息 | AccountType | - |
| extraElements | 顶栏的其他元素 | Array<ExtraElementsType> | - |
| menu | 菜单信息 | Menu | - |
| routerMode | 路由模式 | browser | hash | browser |
| routerBasename | 基准url,browser路由时可传递 | string | - |
| pathMatchMode | path匹配模式 | complete | prefix | complete |
| MainContentComponent | 无菜单时的内容 | (props: Record<string, any>) => ReactElement | - |
| locale | 语言环境 | zh-cn | zh-tw | en-us | zh-cn |
AccountType
| name | 账号名称 | string | - |
| items | 下拉选项的内容 | Array<AccountItemType> | - |
| onClick | 下拉选项的点击事件 | (keys: Array<string>, props?: Record<string, any>) => void | - |
AccountItemType
| key | 唯一标志 | string | - |
| label | 标题 | string | - |
| selectable | 是否可选中 | boolean | true |
| divider | 是否有下划线 | boolean | false |
| children | 子项 | Array<{ key: string; label: string }> | - |
| defaultSelectedKeys | | Array<string> | - |
ExtraElementsType
| icon | 图标 | React.ReactElement | - |
| key | 唯一标志 | string | - |
| label | 标题 | string | React.ReactElement | - |
| onClick | 点击事件 | (key: string, props?: Record<string, any>) => void | - |
| float | 定位 | left | right | right |
Menu
| items | 导航菜单数组 | Array<MenuType> | - |
| getItems | 导航菜单函数,items 和 getItems 二选一 | () => Array<MenuType> | - |
| menuResizeDisabled | 是否禁止调整菜单宽度 | boolean | false |
| defaultCollapsed | 菜单是否收起 | boolean | false |
| onCollapsedChange | 菜单展开、收起事件 | (collapsed: boolean) => void | - |
| defaultMenuWidth | 菜单宽度 | number | 240 |
| onMenuWidthChange | 菜单宽度发生变化 | (menuWidth: number) => void | - |
| onPathChange | 路由发生变化 | (param: { keys: Array<string>; path: string; isPathExist: boolean }) => void | - |
| viewAllIcon | 自定义查看全部菜单的按钮 | ViewAllIconType | - |
MenuType
| key | 唯一标志 | string | - |
| label | 菜单标题 | React.ReactNode | - |
| title | 设置收缩时展示的悬浮标题 | string | - |
| icon | 菜单图标 | React.ReactElement | - |
| path | 路由 | string | - |
| app | 子应用或者主应用组件 | AppType | (props: Record<string, any>) => ReactElement) | - |
| paths | 路由数组(when 一个菜单对应多个路由) | Array<string> | - |
| apps | 子应用或者主应用组件数组(when 一个菜单对应多个路由),和paths一一对应 | Array<AppType | (props: Record<string, any>) => ReactElement)> | - |
| isInMenu | path是否在菜单中 | boolean | true |
| style | 当前页的样式,和path、app一起的 | Record<string, any> | {} |
| children | 子项。当path、app存在时,没有子项 | Array<MenuType> | - |
AppType
| name | 子应用name | string | - |
| entry | 子应用entry | string | - |
| props | 传递给该子应用的props | Record<string, any> | - |
ViewAllIconType
| icon | icon | React.ReactElement | - |
| label | icon的label | string | - |
| content | 内容 | React.ReactElement | ((props: Record<string, any>) => React.ReactElement) | - |
| closeIcon | 是否显示关闭按钮 | boolean | false |
| maskZIndex | 遮罩层的z-index | number | 1 |
2、HeadBar
顶栏
示例
<HeadBar
logo={'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'}
extraElements={[
{
label: '工作台',
key: 'key1',
float: 'left',
},
{
label: (
<Dropdown overlay={menu}>
<div style={{
width: '150px',
textOverflow: 'ellipsis',
overflow: 'hidden',
whiteSpace: 'nowrap'
}}>
我是一个很长只是网络哈哈哈哈
<DownOutlined />
</div>
</Dropdown>
),
key: 'key2',
float: 'left',
onClick: (key) => {
},
},
{
icon: <CiOutlined />,
label: 'API文档',
key: 'key333',
float: 'right',
onClick: (key) => {
},
},
{
icon: <CiOutlined />,
label: '系统配置',
key: 'key333444',
float: 'right',
onClick: (key) => {
},
},
]}
account={{
name: 'admin',
items: [
{
label: '语言',
key: 'language',
children: [
{
label: '简体中文',
key: 'zh-cn',
},
{
label: '繁体中文',
key: 'zh-tw',
},
{
label: 'English',
key: 'en-us',
}
],
defaultSelectedKeys: ['en-us'],
},
{
label: '退出',
key: 'logout',
},
],
onClick: (keys) => {
},
}}
/>
API
HeadBarPropsType
| className | class | string | - |
| logo | base64的logo,不可同时存在 | string | - |
| logoSrc | logo图片的src,不可同时存在 | string | - |
| logoElement | logo元素,不可同时存在 | React.ReactElement | - |
| account | 账号信息 | AccountType | - |
| extraElements | 顶栏的其他元素 | Array<ExtraElementsType> | - |
| props | 额外的props信息 | Record<string, any> | - |
| themeMode | 主题模式 | dark | light | dark |
| style | 样式 | Record<string, any> | - |
侧边栏
示例
<SideBar
openKeys={[]}
selectedKeys={[]}
locale={'en-us'}
theme={'red'}
customStyle={false}
menuWidth={300}
items={menusItems}
height={300}
/>
API
SideBarPropsType
| items | 菜单 | Array<MenuItemType> | - |
| selectedKeys | 当前选中的菜单项 key 数组 | Array<string> | [] |
| openKeys | 当前展开的菜单项 key 数组(仅展开侧边栏时生效) | Array<string> | [] |
| height | 高度 | number | string | 100% |
| menuWidth | 菜单宽度(展开时侧边栏的宽度) | number | 240 |
| theme | 主题色 | string | #126EE3 |
| collapsed | 侧边栏是否收起 | boolean | false |
| locale | 语言环境 | zh-cn | zh-tw | en-us | zh-cn |
| menuResizeDisabled | 是否禁止调整菜单宽度 | boolean | false |
| onCollapsedChange | 菜单展开、收起事件 | (collapsed: boolean) => void | - |
| onMenuWidthChange | 菜单宽度发生变化事件 | ({ width, expandedWidth }: { width: number; expandedWidth: number; }) | - |
| onSelectedKeysChange | 菜单项选中事件 | (selectedKeys: Array<string>) => void | - |
| onOpenKeysChange | 菜单项展开收起事件 | (openKeys: Array<string>) => void | - |
| viewAllIcon | 自定义查看全部菜单的按钮 | ViewAllIconType | - |
4、useBlocker
拦截路由,用于在路由发生变化时给用户做一个提醒。
示例
import { useState, useRef } from 'react'
import { Modal } from 'antd'
export default function UnsavedPrompt({ when, useBlocker }: any): JSX.Element {
const [open, setOpen] = useState(false)
const blockRef = useRef<any>(null)
useBlocker((tx) => {
setOpen(true)
blockRef.current = tx
}, when)
return (
<Modal
visible={open}
onOk={() => blockRef.current?.retry()}
onCancel={() => setOpen(false)}
>
<p className='text-center text-light-700 text-sm'>
这里是提示内容
</p>
</Modal>
)
}
import UnsavedPrompt from './UnsavedPrompt'
import { useBlocker } from 'workshop-framework'
const Demo = (props) => {
return (
<div>
Demo的内容
<UnsavedPrompt useBlocker={useBlocker} />
{/* 两种都可 <UnsavedPrompt useBlocker={props.useBlocker} /> */}
</div>
)
}
export default Demo
5、loadMicroApp
qiankun 的 loadMicroApp,便于子应用加载子应用
6、prefetchApps
qiankun 的 prefetchApps,用于手动预加载指定的微应用静态资源