{"id":23953814,"url":"https://github.com/hsl947/react-antd-multi-tabs-admin","last_synced_at":"2025-09-12T13:31:03.198Z","repository":{"id":37754540,"uuid":"248490902","full_name":"hsl947/react-antd-multi-tabs-admin","owner":"hsl947","description":"ts+react+antd-多页签后台模板(纯净版，非 antd pro！)","archived":false,"fork":false,"pushed_at":"2023-11-28T09:21:26.000Z","size":5063,"stargazers_count":575,"open_issues_count":20,"forks_count":137,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-01-06T14:49:42.426Z","etag":null,"topics":["admin","admin-dashboard","ant-design","ant-design-pro","antd","boilerplate","dashboard","hooks","multitabs","react","redux","tabs","typescript"],"latest_commit_sha":null,"homepage":"https://react-antd-multi-tabs-admin.4everland.website/","language":"Less","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hsl947.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":null,"patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2020-03-19T11:55:30.000Z","updated_at":"2025-01-03T02:32:23.000Z","dependencies_parsed_at":"2025-01-07T03:02:39.512Z","dependency_job_id":null,"html_url":"https://github.com/hsl947/react-antd-multi-tabs-admin","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/hsl947/react-antd-multi-tabs-admin","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsl947%2Freact-antd-multi-tabs-admin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsl947%2Freact-antd-multi-tabs-admin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsl947%2Freact-antd-multi-tabs-admin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsl947%2Freact-antd-multi-tabs-admin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hsl947","download_url":"https://codeload.github.com/hsl947/react-antd-multi-tabs-admin/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hsl947%2Freact-antd-multi-tabs-admin/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274821105,"owners_count":25356214,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-12T02:00:09.324Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["admin","admin-dashboard","ant-design","ant-design-pro","antd","boilerplate","dashboard","hooks","multitabs","react","redux","tabs","typescript"],"created_at":"2025-01-06T14:46:38.305Z","updated_at":"2025-09-12T13:31:02.770Z","avatar_url":"https://github.com/hsl947.png","language":"Less","funding_links":[],"categories":["Less"],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eAntd Multi Tabs Admin\u003c/h1\u003e\n\n\u003cdiv align=\"center\"\u003e🛠️Antd多标签页后台管理模板🛠️\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n由于业务上有多页签需求，网上找了一圈，都是基于antd pro的模板，太重了，不喜欢😒。\u003cbr/\u003e\n于是自己从以前的框架上改造，搭了这么一个精简版框架，用得也舒服，原创🤪。\n\n[预览地址](https://react-antd-multi-tabs-admin.4everland.website/#/)\n\u003c/div\u003e\n\u003cbr /\u003e\n\n## 特性\n\n- 📐: **代码规模**：原创精简版脚手架，主张最少，不臃肿\n- 🚅: **追求前沿**：全站使用 `React Hooks` 开发，抛弃 `Class`\n- 💎: **优雅美观**：基于 `Ant Design` 体系精心设计\n- 🚀: **流行技术**：使用 `React/Redux/Antd` 等前端前沿技术开发\n- 🎨: **主题样式**：使用流行的`暗黑模式`主题，支持`深/浅色`主题切换\n\n## 特点\n\n- 多 tab 页签➕右键菜单，提升效率\n- Redux / Toolkit 状态管理➕持久化\n- 封装实用 axios 请求\n- 动态链式面包屑导航\n- 菜单页面路由权限控制\n- less➕css module 样式隔离, 简单样式则可以使用tailwindcss class来替代\n- 列表➕分页➕多选➕搜索联动组件\n- 可自定义 webpack 配置➕优化打包\n- api请求模拟(MSW)\n- 单点登录(OpenId Connect)集成\n\n## 近期规划\n\n- 尝试多种主题色切换或取色器动态换肤功能（调研开发中👀）\n- 集成单元测试 jest + enzyme，争取覆盖率100%💪🏻💪🏻（学习中🤫）\n\n## 动态主题\n\n目前 `antd@4.17.0-alpha.0` 已支持[动态主题](https://ant.design/docs/react/customize-theme-variable-cn)（实验性），感兴趣的话可以去玩玩，互相探讨。\n\u003cbr /\u003e\n\n### 预览图\n\n![](https://github.com/hsl947/hsl947.github.io/raw/master/images/antd-admin-1.png)\n![](https://github.com/hsl947/hsl947.github.io/raw/master/images/antd-admin-2.png)\n![](https://github.com/hsl947/hsl947.github.io/raw/master/images/antd-admin-3.png)\n![](https://github.com/hsl947/hsl947.github.io/raw/master/images/antd-admin-4.png)\n![](https://github.com/hsl947/hsl947.github.io/raw/master/images/antd-admin-5.png)\n\u003cbr /\u003e\n\n## 使用\n\n### 使用命令行\n\n```bash\n$ npm install -g typescript\n$ git clone https://github.com/hsl947/react-antd-multi-tabs-admin.git\n$ yarn install\n$ yarn start         # 访问 http://localhost:666\n```\n\n### 权限控制\n\n\u003cp\u003e如果不需要权限控制，可自行注释去掉权限功能。\u003c/p\u003e\n\n```\n# src/components/common/menu/index.tsx\n\n// 创建可展开的第一级子菜单\nconst creatSubMenu = (data: any): JSX.Element =\u003e {\n  // const menuItemList = []\n  // data.routes.map((item: any) =\u003e {\n  //   const arr = permission.filter((ele: any) =\u003e item.key === ele.code)\n  //   if (arr.length \u003e 0) {\n  //     menuItemList.push(renderMenu(item))\n  //   }\n  //  return arr\n  // })\n\n  const menuItemList = data.routes.reduce(\n    (prev: any, next: any) =\u003e [...prev, renderMenu(next)],\n    []\n  )\n\n  return menuItemList.length \u003e 0 ? (\n    \u003cSubMenu key={data.key} title={subMenuTitle(data)}\u003e\n      {menuItemList}\n    \u003c/SubMenu\u003e\n  ) : null\n}\n```\n\n```\n# src/pages/container/index.tsx\n\n// 检查权限\nconst checkAuth = (newPathname: string): boolean =\u003e {\n  // 不需要检查权限的\n  // if (noCheckAuth.includes(newPathname)) {\n  //   return true\n  // }\n  // const { tabKey: currentKey } = getKeyName(newPathname)\n  // return isAuthorized(currentKey)\n\n  // 一定返回 true\n  return !!newPathname\n}\n\n```\n\n```\n# src/components/common/tabPanes/index.tsx\n\n// 移除tab\nconst remove = (targetKey: string): void =\u003e {\n  const delIndex = panes.findIndex(\n    (item: CommonObjectType) =\u003e item.key === targetKey\n  )\n  panes.splice(delIndex, 1)\n\n  // 删除非当前tab\n  if (targetKey !== activeKey) {\n    const nextKey = activeKey\n    setPanes(panes)\n    setActiveKey(nextKey)\n    storeTabs(panes)\n    return\n  }\n\n  // 删除当前tab，地址往前推\n  const nextPath = curTab[delIndex - 1]\n  const { tabKey } = getKeyName(nextPath)\n  // 如果当前tab关闭后，上一个tab无权限，就一起关掉\n  // if (!isAuthorized(tabKey) \u0026\u0026 nextPath !== '/') {\n  //   remove(tabKey)\n  //   history.push(curTab[delIndex - 2])\n  // } else {\n  //   history.push(nextPath)\n  // }\n  history.push(nextPath)\n  setPanes(panes)\n  storeTabs(panes)\n}\n```\n\n### Redux/Toolkit 的使用说明\n\n你仍然可以使用 `redux` @Reduxjs/Toolkit是 Redux的封装.使用如下 Reduxjs/Toolkit 用于减少redux模板代码, 按照`就近原则`, 分割代码. 一个状态管理容器切片示例如下.\n\n```\n# 在/src/store/slicers\nimport { createSlice } from '@reduxjs/toolkit'\nimport type { RootState } from '@/store' // typescript intelligence\n\nexport interface AppState {\n  theme: string\n  collapsed: boolean // 菜单收纳状态, 用于垂直布局\n  menuMode: 'horizontal' | 'vertical' // 菜单模式, 用于水平布局\n}\n\nconst initialState: AppState = {\n  collapsed: false,\n  theme: 'dark',\n  menuMode: 'horizontal'\n}\n\nexport const appSlice = createSlice({\n  name: 'app',\n  initialState,\n  // The `reducers` field lets us define reducers and generate associated actions\n  reducers: {\n    setTheme(state, action) {\n      state.theme = action.payload\n    },\n    // ... other setters\n  }\n})\n\n// actions\nexport const { setCollapsed, setTheme, setMenuMode } = appSlice.actions\n\n// getters\nexport const selectTheme = (state: RootState) =\u003e state.app.theme\nexport const selectCollapsed = (state: RootState) =\u003e state.app.collapsed\nexport const selectMenuMode = (state: RootState) =\u003e state.app.menuMode\n// 返回 已切片的 reducer\nexport default appSlice.reducer\n\n```\n\n### 路由/菜单配置\n\n```\n# 所有路由写在 /src/route/routes.ts （包括菜单栏的路由）\n  用于路由权限控制\n\n# 菜单路由基于路由生成, 路由项上增加额外字段标识: 是否在菜单栏展示,及图标等信息\n\n# 你也可以分开写, 增强带单定制功能.\n```\n\n### 关于换肤配置\n\n\u003e 本框架是使用 less.js 实现动态切换主题，js文件在 /public/less.min.js\n\n```\n# 主题配置文件在 /public/color.less\n\n引用了 antd 组件后，基本不需要自己额外自定义主题样式，因为主题文件里都有。\n但是！！！\n如果自己写了自定义组件，切换主题后样式显示不正常，\n则需要自己在 color.less 底部添加深浅主题对应的样式，具体参考主题文件内额外配置。\n\n```\n\n## 支持环境\n\n现代浏览器及 IE11。\n\n| [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png\" alt=\"IE / Edge\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eIE / Edge | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png\" alt=\"Firefox\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eFirefox | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png\" alt=\"Chrome\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eChrome | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png\" alt=\"Safari\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eSafari | [\u003cimg src=\"https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png\" alt=\"Opera\" width=\"24px\" height=\"24px\" /\u003e](http://godban.github.io/browsers-support-badges/)\u003c/br\u003eOpera |\n| --------- | --------- | --------- | --------- | --------- |\n| IE11, Edge| last 2 versions| last 2 versions| last 2 versions| last 2 versions\n\n## 参与贡献\n\n我们非常欢迎你的贡献，你可以通过以下方式和我们一起共建 :smiley:：\n\n- 通过 [Issue](https://github.com/hsl947/react-antd-multi-tabs-admin/issues) 报告 bug。\n- 提交 [Pull Request](https://github.com/hsl947/react-antd-multi-tabs-admin/pulls) 一起改进。\n\n## 友情赞助 - Sponsor\n\n\u003cp\u003e开源不易，请我们喝一杯咖啡，我们会更有动力 :smiley:\u003c/p\u003e\n\u003cp\u003eOpen source is not easy, invite us to drink a cup of coffee, we will be more motivated.\u003c/p\u003e\n\u003cdiv\u003e\n  \u003cimg src=\"./sponsor-imgs/wx.jpg\" height=\"200\" style=\"display: inline-block;\"/\u003e\n  \u003cimg src=\"./sponsor-imgs/zfb.jpg\" height=\"200\" style=\"display: inline-block;\"/\u003e\n  \u003cimg src=\"./sponsor-imgs/eth.png\" height=\"200\" style=\"display: inline-block;\"/\u003e\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhsl947%2Freact-antd-multi-tabs-admin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhsl947%2Freact-antd-multi-tabs-admin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhsl947%2Freact-antd-multi-tabs-admin/lists"}