@kordar/easyui-tpl
v2.0.9
Published
基于 `rc-easyui`、`@kordar/easyui` 与 `@kordar-lib/*` 生态构建的后台模板工程。项目内置布局、菜单/标签联动、权限校验、国际化、后台资源管理页面示例,可直接作为 React 管理后台项目的起步模板,也适合作为二次封装 EasyUI 业务组件的参考工程。
Readme
@kordar/easyui-tpl
基于 rc-easyui、@kordar/easyui 与 @kordar-lib/* 生态构建的后台模板工程。项目内置布局、菜单/标签联动、权限校验、国际化、后台资源管理页面示例,可直接作为 React 管理后台项目的起步模板,也适合作为二次封装 EasyUI 业务组件的参考工程。
目录
项目定位与特性
本模板聚焦“后台基础壳 + 通用业务页 + EasyUI 交互封装”三类能力:
- 布局能力:
BaseLayout提供头部工具区、侧边栏、标签页、内容区联动 - 列表与表单:
useLocalTable、useTable、PaginationPanel、通用表单与表格工具函数 - 权限体系:基于
@kordar-lib/base与 reducers 的权限校验、按钮显隐、页面跳转保护 - 国际化:
@kordar-lib/i18n集成,内置en/zh_CN示例语言包 - 主题切换:通过
SettingBarItem与@kordar/easyui的useTheme()打通本地主题切换 - 示例页面:提供用户、角色、权限、字典、路由、设置、登录、首页、大屏设计等后台页面
适用场景:
- 快速搭建基于
rc-easyui的 React 管理后台 - 沉淀企业后台“布局 + 表格 + 权限 + 国际化”的统一工程模板
- 作为二次封装
@kordar/easyui业务组件的宿主工程
快速开始
安装
npm install本地开发
npm run -w @kordar/easyui-tpl dev默认 Vite 入口为 examples/main.tsx。
构建
npm run -w @kordar/easyui-tpl build构建产物输出到 dist,包含:
- ESM:
dist/index.js - CJS:
dist/index.umd.cjs - 样式:
dist/index.min.css
最小接入示例
import React from 'react'
import ReactDOM from 'react-dom/client'
import { BrowserRouter } from 'react-router-dom'
import { Provider } from 'react-redux'
import { PersistGate } from 'redux-persist/integration/react'
import App from './App'
import './init'
import './example.scss'
import { persistor, store } from './store'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>
)项目结构总览
easyui-tpl/
├── src/
│ ├── components/ # 基础组件与工具条组件
│ ├── composable/ # 页面启动、表格、菜单与刷新 Hook
│ ├── hoc/ # 文档/配置增强 HOC
│ ├── service/ # Admin/Rbac/Resource/Auth/Config 服务层
│ ├── util/ # 表单、表格、懒加载、辅助函数
│ ├── views/ # 后台业务页面模块
│ ├── init.ts # request / api 注册入口
│ └── index.ts # 对外导出入口
├── examples/ # 可运行示例工程(入口、路由、Store、Mock)
├── public/ # i18n 语言包
├── README.md
└── vite.config.ts目录职责说明:
src/components:布局、语言切换、主题切换、分页、提示、用户菜单等src/composable:应用启动、菜单与标签联动、本地/远程表格、路由跳转、刷新控制等src/service:统一封装资源接口、认证接口、配置接口src/views:开箱即用的后台页面示例examples:本地演示应用与调试入口
初始化与运行机制
1. 安装 request 与 API 映射
examples/init.ts 展示了语言包、EasyUI locale 包、接口地址与 request 实例的初始化方式:
import { install } from '../src'
import { request } from './util/http'
install({
request,
apis: {
menus: 'menus',
loginSubmit: 'login/submit',
adminInfo: 'resource/admin/info',
},
})2. 应用启动
根组件通过 useAppStarter() 完成语言包同步与登录态重定向:
import { LocaleProvider, Messager } from 'rc-easyui'
import { useAppStarter } from '../src'
import { alertMessagerRef, interactiveMessagerRef } from '@kordar/easyui'
function App() {
const { easyuiLangPkg } = useAppStarter()
return (
<LocaleProvider locale={easyuiLangPkg?.value}>
<>
<BaseRouter />
<Messager ref={alertMessagerRef} />
<Messager ref={interactiveMessagerRef} />
</>
</LocaleProvider>
)
}3. 页面渲染链路
典型页面渲染流程如下:
install()注册request与 API 表useAppStarter()载入当前语言包并执行自动跳转BaseLayout读取菜单、固定欢迎页、权限列表useMenuAndTabData()维护侧栏和标签页联动- 业务页通过
withDocHoc()注入pageConfig / fetchConfig - 表格页通过
useLocalTable()或useTable()管理分页、搜索、刷新与权限
导出模块清单
src/index.ts 当前主要导出如下能力:
组件与 HOC
| 模块 | 导出名 | 说明 |
| --- | --- | --- |
| 布局组件 | BaseLayout | 后台主布局壳 |
| 工具条组件 | LocaleBarItem | 语言切换菜单 |
| 工具条组件 | PaginationPanel | 分页栏桥接组件 |
| 工具条组件 | SettingBarItem | 主题切换入口 |
| 提示组件 | Tooltip | 文本溢出提示组件 |
| HOC | withDocHoc | 页面语言与后台配置注入 |
| Context | AppLayoutContext | 布局上下文 |
Hook / 工具 / 服务 / 页面
| 分类 | 导出名 | 说明 |
| --- | --- | --- |
| Hook | useMenuAndTabData | 菜单与标签页联动 |
| Hook | useAppStarter | 应用启动初始化 |
| Hook | useLocalTable | 本地表格状态封装 |
| Hook | useTable | 远程表格状态封装 |
| Hook | useAppRedirect | 路由跳转保护 |
| 服务 | resourceService / rbacService / adminService / configService | 资源、权限、管理员、配置接口封装 |
| 页面 | AdminView / RolesView / PermissionsView / DictView 等 | 业务页面模块 |
核心组件模块说明与使用方法
本章只说明模板工程内部已经封装完成、并能直接在项目中复用的核心模块。所有示例均基于当前仓库真实源码组织,并优先沿用 examples 中的使用方式。
BaseLayout
源码位置
功能定位
- 提供后台统一骨架:头部栏、侧边栏、标签页、主内容区、页脚
- 负责菜单树加载、标签页同步、当前路由切换与权限加载
- 适合作为整个后台应用的根布局组件
适用场景
- 多菜单、多标签页的管理后台
- 需要统一接入用户栏、语言切换、主题切换的项目
- 需要把业务页面通过路由
Outlet渲染到主工作区的工程
基础参数
| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| footer | React.ReactNode | undefined | 传入页脚区域内容 |
| ...props | any | - | 其余属性原样透传给 @kordar/easyui 的 FullBodyLayout |
固定内部配置:
tabsCfg = { border: false, plain: true, scrollable: true, narrow: false }sideCfg = { border: false, animate: true, multiple: true, showCollapsedText: false }
基础调用
import { BaseLayout } from '@kordar/easyui-tpl'
export default function AppLayout() {
return (
<BaseLayout footer={<span>Powered by Kordar</span>}>
{/* BaseLayout 内部会自行渲染 TabsPanel 与 <Outlet /> */}
</BaseLayout>
)
}进阶调用
import { Layout } from 'antd'
import { TabsPanel } from '@kordar/easyui'
import { BaseLayout } from '@kordar/easyui-tpl'
export default function CustomLayout() {
return (
<BaseLayout footer={<span>Footer Area</span>} className="app-layout">
<Layout style={{ padding: '4px', height: 48 }}>
<TabsPanel data={[]} tabsCfg={{ scrollable: true }} />
</Layout>
<Layout style={{ padding: 12, height: '100%' }}>
<div>这里放自定义业务面板</div>
</Layout>
</BaseLayout>
)
}事件列表
| 事件 / 回调 | 触发时机 | 回调参数 | 说明 |
| --- | --- | --- | --- |
| toggle(value) | 点击折叠/展开侧边栏 | value: boolean | 由内部调用 setSidebarCollapsed() 更新状态 |
| sidebarCfg.onItemClick(selection) | 点击侧栏菜单项 | selection: SideBarItem | 内部映射到 onMenuSelection() |
说明:BaseLayout 本身没有额外向外暴露 React 事件 props,但会透传底层 FullBodyLayout 的能力。
实例方法
- 无额外对外
ref方法
预览区域
建议运行
npm run dev后进入示例应用,重点观察:
- 左侧菜单切换
- 顶部
User / Locale / Theme工具条- 标签页关闭与当前路由联动
LocaleBarItem
源码位置
功能定位
- 提供头部语言切换菜单
- 基于
@kordar/easyui的useLocale(true)切换当前语言,并刷新页面资源
适用场景
- 中英文后台
- 需要把
rc-easyuilocale 与业务语言包同步切换的工程
基础参数
该组件当前不接收额外 props。
基础调用
import { LocaleBarItem } from '@kordar/easyui-tpl'
export default function HeaderRight() {
return <LocaleBarItem />
}进阶调用
import { BaseLayout, LocaleBarItem } from '@kordar/easyui-tpl'
export default function LayoutWithLocale() {
return (
<BaseLayout
slots={{
barRight: <LocaleBarItem />,
}}
/>
)
}事件列表
| 事件 / 回调 | 触发时机 | 回调参数 | 说明 |
| --- | --- | --- | --- |
| onMenuItemClick | 选择语言项时 | key: string | 内部绑定到 changeLocale() |
实例方法
- 无额外实例方法
预览区域
运行示例后,点击头部语言图标,验证
MenuButton展开、语言切换以及文案刷新效果。
SettingBarItem
源码位置
功能定位
- 提供主题切换抽屉入口
- 使用
DrawerPanel + Panel + RadioButton构建主题配置面板
适用场景
- 需要支持多主题后台
- 希望把主题切换能力统一放在顶部工具区
基础参数
该组件当前不接收额外 props。
基础调用
import { SettingBarItem } from '@kordar/easyui-tpl'
export default function HeaderTheme() {
return <SettingBarItem />
}进阶调用
import { SettingBarItem } from '@kordar/easyui-tpl'
function RightBar() {
return (
<>
<SettingBarItem />
</>
)
}事件列表
| 事件 / 回调 | 触发时机 | 回调参数 | 说明 |
| --- | --- | --- | --- |
| onClick | 点击调色板按钮时 | MouseEvent | 内部调用 ref.current.toggle() 打开抽屉 |
| onChange | 主题单选框切换时 | checked: boolean | 内部触发 changeTheme(value) |
实例方法
- 对外无
ref方法 - 内部依赖
DrawerPanel的toggle()方法控制开关
预览区域
建议截取“主题抽屉展开 + 多个 RadioButton 主题项”的界面作为组件截图。
PaginationPanel
源码位置
功能定位
- 把表格上下文中的分页状态桥接到
rc-easyui/Pagination - 统一分页栏配置,降低各页面重复样板代码
适用场景
- 所有基于
TableContext的列表页 - 使用
useLocalTable()或useTable()的分页列表页面
基础参数
| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| ctx | TableContext | 必填 | 需要提供 pageChange(pageNumber, pageSize) 方法 |
| ctxState | TableContextState | 必填 | 分页状态容器,提供 total/pageNumber/pageSize/layout/pageSizes |
基础调用
import { PaginationPanel } from '@kordar/easyui-tpl'
function PageFooter({ ctx, ctxState }: any) {
return <PaginationPanel ctx={ctx} ctxState={ctxState} />
}进阶调用
import { PaginationPanel, useTable } from '@kordar/easyui-tpl'
function UserTablePage() {
const [ctx, ctxState] = useTable({ defaultPageSize: 20 }, '')
return (
<>
<div style={{ minHeight: 320 }}>表格区域</div>
<PaginationPanel ctx={ctx} ctxState={ctxState} />
</>
)
}事件列表
| 事件 / 回调 | 触发时机 | 回调参数 | 说明 |
| --- | --- | --- | --- |
| ctx.pageChange(pageNumber, pageSize) | 分页变更时 | pageNumber: number, pageSize: number | 由 Pagination.onPageChange 转发 |
实例方法
- 无额外实例方法
预览区域
建议在列表页底部截图分页条,重点保留页码、总数、刷新按钮区域。
Tooltip
源码位置
功能定位
- 为溢出文本提供轻量级提示层
- 支持 hover / click / focus 三种触发方式
- 支持自动翻转、跟随鼠标、深浅主题切换
适用场景
- 表格超长字段
- 面包屑或标题溢出展示
- 需要轻量级 tooltip 且不依赖第三方重型提示组件的场景
基础参数
| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| text | ReactNode | 必填 | Tooltip 展示内容 |
| children | ReactNode | 必填 | 被包裹的触发节点 |
| position | 'top' \| 'bottom' \| 'left' \| 'right' | 'bottom' | 提示层方向 |
| trigger | 'hover' \| 'click' \| 'focus' | 'hover' | 触发方式 |
| delay | number | 50 | 延迟显示时间,单位 ms |
| maxWidth | number | 250 | 最大宽度 |
| theme | 'dark' \| 'light' | 'dark' | 样式主题 |
| followMouse | boolean | false | 是否跟随鼠标 |
| autoFlip | boolean | true | 空间不足时是否自动翻转方向 |
基础调用
import { Tooltip } from '@kordar/easyui-tpl'
export default function NameCell() {
return (
<Tooltip text="这是完整内容" position="bottom">
<span style={{ display: 'inline-block', width: 120, overflow: 'hidden', textOverflow: 'ellipsis' }}>
这是完整内容
</span>
</Tooltip>
)
}进阶调用
import { Tooltip } from '@kordar/easyui-tpl'
export default function HoverCard() {
return (
<Tooltip
text={<div>可跟随鼠标展示更长的提示内容</div>}
trigger="hover"
position="right"
followMouse
theme="light"
maxWidth={320}
>
<div style={{ width: 180 }}>将鼠标移动到这里</div>
</Tooltip>
)
}事件列表
该组件不对外暴露额外回调 props,内部通过以下 DOM 事件驱动显示逻辑:
onMouseEnter / onMouseLeaveonMouseMoveonClickonFocus / onBlur
实例方法
- 无额外实例方法
预览区域
建议在表格超长文本场景截图,展示默认隐藏、悬停后浮层出现的前后对比效果。
withDocHoc
源码位置
功能定位
- 为业务页面统一注入:
pageConfig:当前页面对应语言包fetchConfig:页面初始化配置数据fetchVersion:配置重新拉取后的版本号
- 自动同步
document.title
适用场景
- 页面需要按语言包动态生成标题、按钮文案、表格列名
- 页面需要在加载时请求配置项,如字典、枚举、状态列表
基础参数
withDocHoc() 接收一个 DocHocProps 配置对象:
| 参数 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| name | string | 必填 | 页面名称,对应语言包 Page/<name> |
| fetchConfig | () => Promise<any> | undefined | 页面初始化配置请求函数 |
基础调用
import { withDocHoc } from '@kordar/easyui-tpl'
const RolesPage = ({ pageConfig, fetchConfig }: any) => {
return <div>{pageConfig.title}</div>
}
export default withDocHoc({ name: 'Roles' })(RolesPage)进阶调用
import { resourceService, withDocHoc } from '@kordar/easyui-tpl'
const RouterPage = ({ pageConfig, fetchConfig, fetchVersion }: any) => {
return <div>{fetchVersion}: {pageConfig.title}</div>
}
export default withDocHoc({
name: 'Router',
fetchConfig: () => resourceService.configs('router'),
})(RouterPage)注入属性
| 属性 | 类型 | 说明 |
| --- | --- | --- |
| pageConfig | Record<string, any> | 当前页面语言包配置 |
| fetchConfig | Record<string, any> | 后台返回的配置数据 |
| fetchVersion | number | 配置版本号,适合触发下游重渲染 |
事件列表
- 无额外对外事件
实例方法
- 无额外实例方法
AppLayoutContext
源码位置
功能定位
- 用于在布局层向下传递
dispatch、useAppSelector和location等上下文能力 - 主要服务于布局区内部或扩展组件读取全局状态
上下文结构
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| dispatch | AppDispatch | Redux dispatch |
| useAppSelector | TypedUseSelectorHook<RootState> | 类型化 selector |
| location | Location | 当前路由信息 |
基础调用
import { useContext } from 'react'
import { AppLayoutContext } from '@kordar/easyui-tpl'
export default function LayoutConsumer() {
const ctx = useContext(AppLayoutContext)
return <div>{String(!!ctx.dispatch)}</div>
}事件 / 方法
- 无对外事件
- 无实例方法
UserBarItem(内部组件)
源码位置
说明
- 当前未在
src/index.ts中导出 - 由
BaseLayout内部使用,负责显示当前用户名与退出登录菜单
行为特征
- 读取
state.user.info - 点击
Exit后调用$confirm() - 退出时清理布局状态并跳转到
/login
如需对外复用,建议先在 src/index.ts 中显式导出,并补充 props 类型定义。
useAppStarter
源码位置
功能定位
- 应用根组件启动专用 Hook
- 同步当前语言包并执行自动登录态重定向
函数签名
function useAppStarter(): { easyuiLangPkg?: PkgItem }返回值
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| easyuiLangPkg | PkgItem \| undefined | 当前激活的 EasyUI 语言包 |
基础调用
const { easyuiLangPkg } = useAppStarter()useMenuAndTabData
源码位置
功能定位
- 维护菜单、标签页、当前选中项、固定欢迎页等布局核心状态
- 是
BaseLayout侧栏和标签页联动的核心实现
函数签名
function useMenuAndTabData(menuservice: TabMenuService<number>)返回值
| 字段 | 说明 |
| --- | --- |
| collapsed | 侧栏折叠状态 |
| menuList | 当前侧栏菜单树 |
| menuAll | 全量菜单树 |
| onMenuSelection | 菜单点击回调 |
| menuArea | 顶部分组菜单 |
| setMenuAreaId | 切换当前菜单分区 |
| choiceId | 当前选中菜单 ID |
| menuTabList | 当前标签页列表 |
| onTabClosed | 关闭标签页 |
| onTabSelected | 选中标签页 |
useLocalTable / useTable
源码位置
功能定位
useLocalTable:本地数据表格状态封装useTable:远程分页表格状态封装- 两者都会自动注入权限校验器和用户版本号,用于页面刷新控制
函数签名
function useLocalTable(cfg: LocalTableConfig, dependency?: any)
function useTable(cfg: LocalTableConfig, dependency?: any)默认表格状态
{
data: [],
pageNumber: 1,
pageSize: cfg.defaultPageSize ?? 20,
total: 0,
loading: false,
border: false,
pageSizes: [10, 20, 30, 40, 50],
layout: ['list', 'sep', 'first', 'prev', 'links', 'next', 'last', 'sep', 'refresh', 'info'],
style: { width: '100%', height: '100%' },
selectionValues: []
}基础调用
import { useTable } from '@kordar/easyui-tpl'
const [ctx, ctxState] = useTable(
{
defaultPageSize: 20,
checkAccessItems: [],
},
''
)useRefreshKey
源码位置
功能定位
- 通过自增 key 的方式强制触发下游组件刷新
函数签名
function useRefreshKey(): [number, Function]基础调用
const [refreshKey, forceRefresh] = useRefreshKey()useAppRedirect
源码位置
功能定位
- 封装应用登录态跳转与历史地址恢复逻辑
- 基于
@kordar-components/react的useAppRedirect再封装
函数签名
function useAppRedirect()内部依赖
useLocation()state.app.historyLocationAdmin.isGuest()App.saveHistoryLocation(location)
业务页面模块说明
模板内置了可直接复用的后台页面模块,主要用于快速搭建基础系统:
| 页面模块 | 导出名 | 场景说明 | 实现入口 |
| --- | --- | --- | --- |
| 管理员 | AdminView | 管理员列表、搜索、编辑、授权入口 | src/views/admin/index.tsx |
| 首页 | HomeView | 后台首页占位页 | src/views/home/index.tsx |
| 设置 | SettingView | 系统设置列表与编辑 | src/views/setting/index.tsx |
| 登录 | LoginView | 登录页与登录配置读取 | src/views/login/index.tsx |
| 角色 | RolesView | 角色列表、编辑、授权 | src/views/roles/index.tsx |
| 权限 | PermissionsView | 权限列表、编辑、快速新增 | src/views/permissions/index.tsx |
| 字典 | DictView | 字典列表与详情项联动 | src/views/dict/index.tsx |
| 路由 | RouterView | 路由资源管理 | src/views/router/index.tsx |
| 404 | NotFoundView | 未匹配页面 | src/views/page/404.tsx |
| 大屏设计 | ScreenDesign | 大屏设计示例入口 | src/views/srceen/design/index.tsx |
这些页面大多数都采用以下统一模式:
- 使用
withDocHoc({ name, fetchConfig })注入页面语言包与配置数据 - 使用
resourceService.configs(name)或相似服务读取枚举配置 - 通过
TableContext管理搜索、分页、刷新和选择状态
组件模块扩展开发指南
1. 自定义组件目录创建规范
建议遵循现有目录分层,不要把业务组件直接堆在根目录:
src/
├── components/
│ └── MyWidget.tsx
├── composable/
│ └── useMyWidget.ts
├── service/
│ └── MyWidgetService.ts
├── util/
│ └── my-widget.ts
└── views/
└── my-widget/
├── index.tsx
├── search.tsx
├── table.tsx
├── form.tsx
└── context.ts推荐规则:
- 通用组件放
src/components - 页面级状态 Hook 放
src/composable - 接口调用封装放
src/service - 页面级模块放
src/views/<module> - 最终记得在
src/index.ts注册导出
2. 基础模板编写规范
推荐采用当前仓库统一风格:
import React, { FC } from 'react'
export interface MyWidgetProps {
title?: string
onChange?: (value: string) => void
}
const MyWidget: FC<MyWidgetProps> = ({ title = 'Demo', onChange }) => {
return <div className="k-my-widget">{title}</div>
}
export default MyWidget规范建议:
- 优先使用明确的
Props类型,不要长期保留FC<any> - 组件名、文件名、导出名保持一致
- 复杂业务逻辑下沉到 Hook 或 util,不把所有流程堆在组件体内
- 与后台语义强相关的交互,优先封装为回调而不是在外层拼装
3. 样式隔离实现要求
当前工程使用全局 SCSS 与第三方主题样式混合方式,扩展时建议:
- 组件类名前缀统一使用
k-或业务模块前缀,避免污染rc-easyui默认类 - 通用样式合并到
src/index.scss或组件自有样式文件 - 避免直接覆盖
rc-easyui全局基础类,优先加作用域父类 - 主题相关样式优先挂靠
html[theme='xxx']或模板现有主题机制
建议写法:
.k-my-widget {
display: flex;
.k-my-widget__title {
font-weight: 600;
}
}4. 属性注册、事件封装、逻辑扩展流程
推荐扩展流程:
- 在组件内定义清晰的
Props接口 - 把对外可变项收敛为 props,而不是依赖外部全局变量
- 把交互动作通过
onXxx回调暴露出去 - 将数据加载、分页、刷新、权限判断提取到 Hook
- 在
src/index.ts中补齐导出 - 在
examples中补一个可运行演示页面用于调试
一个标准回调封装示例:
export interface SwitchPanelProps {
value?: boolean
onChange?: (value: boolean) => void
}
const SwitchPanel: FC<SwitchPanelProps> = ({ value = false, onChange }) => {
const handleToggle = () => onChange?.(!value)
return <button onClick={handleToggle}>{String(value)}</button>
}5. 通用工具函数、混入逻辑复用方法
当前仓库已提供若干可复用工具,建议优先复用而不是重复实现:
| 工具模块 | 位置 | 适用场景 |
| --- | --- | --- |
| resourceAccessItems() | src/util/form.ts | 生成资源类页面的权限点配置 |
| removeEventFn() / resourceRemoveEvent() | src/util/form.ts | 封装删除确认与成功刷新逻辑 |
| permissionTree() / roleTree() | src/util/helper.ts | 权限树、角色树数据转换 |
| fetchConfigOptions() | src/util/helper.ts | 将后台配置转成下拉选项 |
| renderTooltip() / renderFetchConfigValue() | src/util/tables.tsx | 表格列渲染 |
| Lazy() | src/util/lazy.tsx | 页面级懒加载包装 |
复用建议:
- 表格列展示优先复用
renderTooltip(),统一长文本处理方式 - 资源增删改页面优先复用
resourceAccessItems()和resourceRemoveEvent() - 页面配置项转换优先复用
fetchConfigOptions(),避免重复拼装{ value, text }
6. 扩展组件的单元测试要求
当前包脚本中预留了:
npm test虽然仓库内尚未补齐完整测试目录,但新增组件时建议遵循以下要求:
- 至少覆盖渲染成功、关键 props、生效回调三个层面
- 涉及分页、弹层、菜单选择的组件,重点校验事件分发是否正确
- 涉及权限隐藏的组件,重点校验不同权限组合下的 UI 结果
- Hook 至少校验默认状态、状态流转和边界输入
建议测试目录:
src/components/__tests__/
src/composable/__tests__/建议测试技术栈:
Jest@testing-library/reactjsdom
7. 本地调试流程
推荐调试流程:
- 在
src/中实现或修改组件 - 在
examples中创建一个最小可复现入口 - 执行
npm run dev启动 Vite - 通过浏览器逐项验证布局、事件、权限、国际化、主题切换
- 完成后执行
npm run build验证产物构建
可参考的调试入口:
样式、国际化与主题说明
关键依赖(外部)
- React 生态:
react、react-dom、react-router、react-router-dom、react-i18next - UI:
rc-easyui、rc-drawer、@kordar/easyui、@kordar/react-screen - 工具:
axios、lodash-es - Kordar 库:
@kordar-lib/base、@kordar-lib/i18n、@kordar-lib/menus、@kordar-lib/reducers、@kordar-lib/request
样式
示例样式在 examples/example.scss 中已引入:
@import '@kordar-lib/iconfont/dist/index.min.css';
@import '@kordar/easyui/dist/index.min.css';
@import '@kordar/react-screen/dist/index.min.css';index.html 会按本地持久化主题加载 rc-easyui 主题与 react.css。
国际化
- 语言包文件:
- 初始化入口:
examples/init.ts - 运行时切换入口:
src/components/LocaleBarItem.tsx
初始化(示例)
examples/init.ts 展示了语言包与请求初始化的方式。你可以按需接入实际后端接口,完善登录、菜单、权限等配置。
本地验证与文档自检
本次文档改写的示例校验原则
- 所有组件示例均优先基于当前仓库真实源码组织
- 导入路径均以当前
src/index.ts的真实导出为准 - 内部组件如
UserBarItem已明确标注“未对外导出”
建议本地验证命令
npm run dev
npm run build链接自检清单
- 本 README 中所有文件链接均使用当前仓库内真实存在的相对路径
- 目录跳转使用显式锚点,避免标题重命名导致的 TOC 失效
- 未引入不存在的截图文件或外部失效链接
截图预览区域使用建议
为避免 README 中引用不存在的静态资源导致链接失效,当前文档采用“预览区域说明”方式预留截图位置。建议在你们正式沉淀文档时:
- 从
examples运行页面截取组件真实界面 - 统一放入例如
docs/readme-assets/目录 - 将本 README 中的“预览区域”说明替换为真实图片链接
示例格式:
许可证
MIT
