开源一套特色Admin管理系统(前端)-喜欢拿去(1)

先上个预览地址

admin-react-antd.eluxjs.com

啥特色?

咋一看,感觉不到有啥特色呀?不就是Antd组件做的么?这种开源项目网上不很多吗?

的确,这里所谓的特色并不是UI组件外观多么标新立异,说实话,后台常用的UI组件网上已经很多了,再做也是个轮子工程。

除了看得见的UI界面,其实还有大把技术创新最佳实践可以总结和提炼,比如:架构设计、文件组织、工程化、路由方案、分层解耦、复用代码等等。尤其是对于后台管理系统来说,并不追求个性化,如果我们能自己总结一套最佳实践、大量采用标准模式、标准件,很多代码其实都是复制粘贴然后改改字段而已,那将极大提高我们的劳动生产力,这也是近来流行的低代码平台赖以发展的理论基础...

Restful

Restful作为后端领域的基本概念,其理念同样可以启发前端:任何纷杂的业务动作,其实都可以抽象为对资源的增删改查。而对任何资源的增删改查其实都是有共性可以抽取和提炼的,这不仅反映在代码开发上,同样可以用来指导产品原型与交互设计(设计松散的UI界面、交互原型、路由跳转等,不要每个业务场景都要去定制一套耦合很强的UI与交互,即便是用户体验更好,但也要考虑开发成本、稳定性、可维护性)。

低代码平台

很多低代码平台就是利用表单增删改查来自动生成后台系统,但是我们要考虑一个事情,那就是木桶短边效应,如果低代码平台能解决你99%的业务场景,但当心就是那1%把你坑惨。

我们编程中经常碰到一些优化策略:用时间换空间,或是用空间换时间,不同场景下你看重的维度不一样。同样,复杂度工作量有时候也有点这意思,有时候简单的复制粘贴,看上去不优雅,工作量也大,但它让事情变得很直观简单;相反,你用一些拐弯抹角的魔术变幻、复杂的配置文件来表达同样的效果,反而变得很难维护。不怕事情多,只怕没条理...

项目介绍

好了,喃喃自语了这么多,无非就是想说,这个项目的特色不于与UI组件,而在于破题思路,大家可以一起探讨一下工程源码:

Github:github.com/hiisea/elux…

Gitee:gitee.com/hiisea/elux…

项目基于Elux+React+Antd框架开发,主要用了2个完整的资源的增删改查来进行示例:

  • 提供通用的项目脚手架。

  • 提供通用的Admin系统Layout(包括注册、登录、获取Menu菜单、轮询最新消息等等)

  • 提供收藏夹书签功能,用其代替Page选项卡,操作更灵活。点击左上角【+收藏】试试...

  • 提供<DocumentHead>组件,方便在SinglePage中维护Document Title,你可能会觉得很简单,不就是useEffect去设置document.title吗?但实际上没这么简单,你要考虑到多处同时设置,还有路由回退时的还原操作。

  • 提供通用的列表搜索表单,有高级搜索条件时自动展开高级搜索:展开高级 / 隐藏高级

  • 提供跨页选取、review已选取、批量操作等功能,如:跨页选取及批量操作

  • 在一种资源中,如何查询并引用另外一种资源,如:创建文章时,查询并选择责任编辑,这里的关键是如何复用列表代码。

  • 提供双栈单链虚拟路由,不仅可以拥有二维的历史栈,还能访问历史记录、保持历史快照、对路由编程、等待。

    • 例如登录窗口中点击“取消登录”你需要回退到前一个页面,但此时如果前一个页面就是需要登录的页面,那么登录窗口又会被重新弹出。所以点击“取消登录”应当回退到最近的不需要登录的页面(浏览器原生的history并不能提供给我们访问每条历史记录的能力):
    @effect()
    public async cancelLogin(): Promise<void> {
        //在历史栈中找到第一条不需要登录的记录
        //如果简单的back(1),前一个页面需要登录时会引起循环
        this.getRouter().back((record) => {
          return !this.checkNeedsLogin(record.location.pathname);
        }, 'window');
    }
    复制代码
    • 例如新增用户后,需要返回列表页面并刷新:
    await api.createItem!({id, data}); //await 创建API
    await this.getRouter().back(1, 'window'); //await 返回列表页面
    message.success('新增成功!'); //提示
    this.getRouter().back(0, 'page'); //刷新页面
    复制代码
  • 特色虚拟窗口:

    • 提供路由跳转时新开窗口,类似于原生window.open操作,如:新窗口打开 / 本窗口打开
    • 窗口中可以再开新窗口,最多可达10级
    • 每个窗口不仅拥有独立的Dom、状态管理Store、还自动维护独立的历史记录栈
    • 提供窗口工具条:后退、刷新、关闭,如:文章列表 => 点击标题 => 点击作者 => 点击文章数。然后你可以依次回退每一步操作,也可一次性全部关闭。
    • 支持窗口最大化,如:创建文章
    • 窗口可以通过Url发送,如将http://admin-react-antd.eluxjs.com/admin/member/item/edit/50?__c=_dialog发送给好友后,其可以通过Url还原窗口。
  • 基于抽象的增删改查逻辑:

  • 基于微模块架构,每个业务功能封装成一个独立的功能模块,想要哪个功能就安装哪个模块,并支持异步按需加载,src下不再凌乱不堪:

    src
      ├── modules
      │      ├── stage //总的根模块
      │      ├── admin //admin根模块
      │      ├── dashboard //工作台模块
      │      ├── article //文章模块
      │      ├── comment //评论模块
      │      └── member //用户模块
    复制代码
  • 还有更多彩蛋有待补充,或者自己探索吧...

知其所以然

对于某些特色为什么要这么设计?出发点是什么?到底合不合理?这些议题比较多,一时半会也难以说清楚,后续会陆续发文来详细阐述自己的思路与想法,跟大家一起探讨...

先说第一个吧:

为什么使用微模块

大家以为常的前端工程基本上都长这样:

src
├── assets
├── consts
│      ├── ModuleA
│      │      ├── Const1.ts //A中使用的一些常量
│      ├── ModuleB
│             ├── Const2.ts //B中使用的一些常量
├── utils
├── components
│      ├── ModuleA
│      │      ├── Component1.ts //A中使用的一些UI组件
│      ├── ModuleB
│             ├── Component2.ts //B中使用的一些UI组件
├── containers
├── pages
│      ├── ModuleA
│      │      ├── Page1.ts //A中使用的一些页面
│      ├── ModuleB
│             ├── Page2.ts //B中使用的一些页面
├── models
│      ├── ModuleA
│      │      ├── Store1.ts //A中使用一些状态定义
│      ├── ModuleB
│             ├── Store2.ts //B中使用一些状态定义
│
复制代码

其特点是以“文件职能”作为一级分类、“功能模块”作为次级分类。

现在如果我需要拿掉ModuleB,或者新增ModuleC,你将不得不进行多个目录的操作。随着文件越来越多,相互引用越来越复杂,ModuleB的相关资源和依赖像一堆乱麻散落在各个不同文件和文件夹中,你会发现要干净的剥离ModuleB是一个巨大的任务...

而大家可以看看本项目的源码:

src
  ├── modules
  │      ├── stage 
  │      ├── admin 
  │      ├── dashboard 
  │      ├── article 
  │      ├── comment 
  │      └── member 
复制代码

将“功能模块”作为一级分类,“文件职能”作为次级分类,src目录下是针对独立业务功能的一个个Module(微模块),你要去掉评论模块?整体移除/src/modules/comment文件夹就好,要添加某个功能?把相应的目录拷到/src/modules/下面就好。如果你采用NPM包来管理这些微模块?那更简单,只需要npm remove @you-project/comment或者npm install @you-project/comment

进一步大胆设想,假如我们前端社区一起开发一个大型的类似于worldpress那样的cms系统,先由核心团队搭建起基座模块@cms/stage,后面的社区成员,都可以基于这个基座模块来独立开发不同的业务功能微模块,比如文章模块、评论模块、图片模块、上传模块、投票模块、会员模块、订单模块....然后他们各自将开发的微模块直接发布到npm,用户可以直接npm install来各取所需。

当然上面只是设想,微模块最大的好处还是在于高内聚,低耦合,至于是否要用npm来管理,不是必须的。但它并不增加工作量,只不过在每个微模块目录下,增加一个package.json罢了。如果你不想绕这么一个圈,也可以分分钟改回去:

打开src/tsconfig.json,增加别名:

"paths": {
  "@/*": ["./*"]
}
复制代码

将微模块直接用别名来import

// 将使用npm包名改为使用别名
// import stage from '@elux-admin-antd/stage';
import stage from '@/modules/stage';
复制代码

最后

先写这么多吧,一篇文章讲太多主题容易晕,后续还会挑选一些议题跟大家探讨,未完待续...

另外是否会出Vue版?其实本项目采用了Elux的所谓模型驱动业务层UI层是分离的,使用Vue只需要重写UI层即可,如果采用jsx语法,UI层的重构应当也不是什么很难的事情,后续有时间再说吧,

完全开源免费,喜欢拿去,觉得好用别忘了Github给个Star哦(-_-)...

猜你喜欢

转载自juejin.im/post/7119728761355894814