首页 > 其他分享 >用1100天做一款通用的管理后台框架

用1100天做一款通用的管理后台框架

时间:2024-09-16 10:53:23浏览次数:14  
标签:天做 框架 Element 组件 菜单 UI 1100 后台 Plus

前言

去年年底,我写了一篇《如何做好一款管理后台框架》的文章,这是我对开发 Fantastic-admin 这款基于 Vue 的中后台管理系统框架两年多时间的一个思考与总结。

很意外这么一篇标题平平无奇的文章能收获 30k 的浏览以及 600 多个收藏,似乎大家对这种非干货的文章也挺感兴趣。于是在这个三年的时间点上(没错,也就是1100天),我打算继续出来和大家唠唠,这一年我又做了些什么事,或者说,如何把一款好的后台框架变得通用?

题外话:如果你对我以前的文章感兴趣,可以点我头像进入主页查看;如果你期待我以后的文章,也可以点个关注。

痛点

因为 Fantastic-admin 是基于 Element Plus 这款 UI 组件库进行开发的,于是今年我陆陆续续被问到一些问题:

  • 以后会有 Ant Design Vue 版本么?会有 Naive UI 版本么?会有 …… 版本么?
  • 我们公司/团队有一套内部的 UI 组件库,可以在 Fantastic-admin 里使用么?会和 Element Plus 有冲突么?
  • 我们有一些老项目希望迁移到 Fantastic-admin 上来,但 UI 组件库用的不是 Element Plus ,有什么办法么?

类似的问题一多,我也在思考一个问题:我的这款框架是不是被 Element Plus 绑架了?如果开发者在做技术选型的时候,因为 UI 组件库不符合预期,而将我的框架筛掉,这是我不希望看到的结果。

基于这个潜在隐患,我开始计划对框架进行转型。

方案

方案一

既然开发者对 UI 组件库有各自的偏好,我又想拉拢这部分开发者,那是不是多出几套不同 UI 组件库版本的就可以了呢?没错,这是我最开始冒出来的念头。

我参考了一些同类产品的做法,尽管它们把不同 UI 组件库版本做得很像,但在使用体验过程中,还是会带来操作上的割裂感。并且因为无法抹平不同 UI 组件库在 API 上的差异,导致在框架功能上,不同版本之间也会有一些差异。

用1100天做一款通用的管理后台框架_UI

你可以分别对比左右或者上下两张图,包括左侧导航栏的样式、导航收起/展开按钮的位置、右侧项目配置中提供的功能等,都能明显发现它们的差异。

虽然这可能不是什么大问题,但我认为视觉风格上的统一是能帮助产品提高识别度的。就比如上面 4 款基于不同 UI 组件库开发的后台框架,虽然它们属于同一个产品,但如果我不告诉你,你未必能通过图片确定它们师出同门。

其次就是后台框架提供的功能不统一,这里面有一定的原因是因为 UI 组件库导致的。试想一个场景,如果你要从 Element Plus 版本的后台,迁移到 Ant Design Vue 版本的后台,框架的配置文件是否能原封不动的复制过去?如果导航(路由)数据是后端返回的,数据结构能否保持完全一致,后端无需做任何修改?因为不同 UI 组件库对菜单组件的使用方式是完全不同的,比如 Element Plus 是需要手动拼装的,而 Naive UI 则是数据驱动的,只需要传入一个树形结构的数据给组件即可。如果数据结构无法保证一致,就会增加迁移和学习的成本。

最后就是我的一点私心,因为多一个 UI 组件库的版本,势必会占据我更多的业余时间,如果同时维护 4、5 个版本,那我大概下班后的所有时间都要投入到其中,并且如果未来又有新的 UI 组件库成为流行,那就又多一个版本的维护,这并不是一个可持续发展的方案。

方案二

既然上一个方案不符合我的期望,于是我开始思考,框架本身能不能不依赖这些 UI 组件库?如果框架本身不依赖于三方的 UI 组件库,那开发者不就可以根据需要自行引入想要的组件库了么。

用1100天做一款通用的管理后台框架_Vue_02

就如上图,主/次导航和顶栏是属于框架的部分,而这部分其实并没有用到太多 UI 组件库提供的组件,以 Element Plus 举例,我统计了一下目前 Fantastic-admin 用到的组件:

  • Menu 菜单(主/次导航)
  • Breadcrumb 面包屑(顶栏)
  • Popover 气泡卡片(顶栏右侧的工具栏)
  • Dropdown 下拉菜单(顶栏右侧的工具栏)
  • Drawer 抽屉(应用配置)
  • Message 消息提示
  • Button 按钮
  • Input 输入框
  • Radio 单选框
  • Select 选择器
  • Switch 开关
  • …(等等表单类组件)

可以看到,虽然抽屉组件里用了很多表单类的组件,但这部分组件都是在应用配置里使用的,而应用配置这个模块,主要是方便在线测试框架提供的各种功能,在实际业务开发中,是完全不需要这个模块的。

用1100天做一款通用的管理后台框架_表单_03

所以初步算下来,后台框架真正依赖于 Element Plus 实现的组件就只有 4 个:

  • Menu 菜单
  • Breadcrumb 面包屑
  • Popover 气泡卡片
  • Dropdown 下拉菜单

那我为什么不找一些独立的第三方插件替代呢?是的,这是我第二个方案,就是找一些独立的插件替换 UI 组件库中的组件。但问题也立马迎面而来,就是偌大一个 Github ,居然找不到符合我需求和审美的插件。

比如菜单插件,我希望它和 Element Plus 里的菜单组件在功能上没有太大差异,支持水平/垂直模式、支持折叠收起、支持设置默认激活菜单、支持默认展开等。

比如面包屑插件,或许是因为这个插件功能太简单,并且大部分 UI 组件库都有提供,在 Github 能搜到独立的面包屑插件很少,搜到的也基本上是 N 年前的上传的,既没有人维护,风格样式也很丑。

这个方案似乎也行不通……吗?

方案三

虽然方案二在实施的第一步就扑街了,但有一点思路还是正确的,就是让框架本身不依赖于三方 UI 组件库。既然网上搜不到合适的插件,那我为什么不自己写一个呢。

比如面包屑,这是一个很简单的功能,任何前端初学者应该都可以写一个面包屑组件。

而气泡卡片和下拉菜单我没有计划自己写,因为找到了一个还不错的插件 Floating Vue,它由 Vue 团队核心人员开发并维护,并且最重要的是它支持自定义样式,意味着我可以将它魔改成想要的样子,尽可能和我的框架在视觉风格上保持统一。

最后一个比较难啃的骨头就是菜单,因为找不到合适的替代品,自己写的话又比较有挑战,虽然我有一点实现思路,但不多。当然最终还是决定自己写一个,因为觉得三方 UI 组件库这么多,实在写不出来我就去读他们源码,总不能每一个源码我都读不懂吧。

这 4 个组件的替换方案确定后,剩下就是抽屉组件和它里面的一些表单组件了,这些要怎么解决呢?这会我想到了 Headless UI ,它是完全无样式的 UI 组件库,通过与 Tailwind CSS / UnoCSS 集成使用,可以快速构建出属于自己风格的组件。

但是 Headless UI 提供的组件非常有限,并不能覆盖我需要的表单组件。不过它的设计给了我启发。表单组件我并不需要非常复杂的功能,原生的表单控件其实就能满足我的使用需求,只是原生的样式比较丑,和我想要的风格不统一,那我只需要给他们定制一套统一的风格就可以了,也就写一套原子化的 CSS 样式。

于是,方案敲定,开始实操。

实操

我决定从易到难开始处理,因为这样在初期能快速看到进度推进,也避免一上来就被一个菜单功能卡住好几天,甚至十几天都没有进展,打击到自己的信心。

1. 面包屑

和预期一样,并没有什么难度,很轻松就实现了。只不过目前还是保持和 Element Plus 一样的使用方式,就是需要手动拼装,后期计划改成数据驱动的使用方式。

用1100天做一款通用的管理后台框架_表单_04

2. 气泡卡片 & 下拉菜单

这部分参考了 nuxt/devtoolsFloating Vue 的自定义样式,以及 nuxt/ui 中下拉菜单的样式风格,最终形成了我自己满意的风格

用1100天做一款通用的管理后台框架_表单_05

3. 抽屉

使用了 Headless UI 中的 Dialog 组件,因为它和抽屉组件有相同的交互方式,它们都是在遮罩层上展示内容,只不过 Dialog 更多时候是居中展示,而抽屉则是在左右两侧展示。

其次在使用过程中,发现 Headless UI 中的 Transition 组件是一个惊喜。虽然 Vue 本身就有提供 <transition> 组件用于处理过渡动画,但有一个场景会比较难处理,官方的描述是:

This technique is needed when you want to coordinate different animations for different child elements – for example, fading in a Dialog's backdrop, while at the same time sliding in the contents of the Dialog from one side of the screen. 当您要为不同的子元素协调不同的动画时,就需要使用这种技术,例如,在淡入对话框背景的同时,从屏幕的一侧滑入对话框的内容。

这说的不就是抽屉组件么?于是按照官方的示例,修改了整体风格,最终效果也就出来了。

用1100天做一款通用的管理后台框架_表单_06

4. 表单组件

之前的计划是修改原生表单控件的样式,但在开发过程中发现会有一定的局限性。比如 <select> 无法控制弹出选项框的样式,我的解决办法就是用 Floating Vue 封装模拟一个 select 组件。

同时也在开发过程中发现了一些被遗漏组件,于是边做边补,最终大概做了 10 多个组件。虽然看着不少,它们都秉持着最小可用的状态。什么意思呢?就是我不会给它们设计太多的 API ,因为它们的定位和三方 UI 组件库不同,它们只要满足框架本身使用即可,用不到的 API 不会进行开发。并且使用上也不会有太大负担,如果不是对框架进行二次开发,开发者是可以完全不用关注这部分组件。

用1100天做一款通用的管理后台框架_表单_07

5. 菜单

菜单组件确实是个难啃的骨头,我差不多用了 3 周的晚上时间去开发。

第一周,按照自己的思路徒手撸,做到一半卡壳,做不下去了;

第二周,开始看 Element Plus 、Naive UI 、Ant Design Vue 里菜单的源码;

Ant Design Vue 的没看懂,放弃;

Naive UI 的看到一半发现核心实现被作者封装到 treemate 这个独立包中了,虽然这个包是开源的,目的也是针对树形结构的一体化解决方案。但我粗略看了一遍文档,感觉有点大材小用,因为它有很多 API 我是用不到的,而我对菜单组件又有一些自己的想法,不确定是否它这个包能否满足我的需求,放弃;

最后选择看 Element Plus 的,通过在本地一点点打印数据,大概理解了实现思路,但组件递归调用,父子组件通过 provide / inject 传递数据和函数的方式,数据状态的变动也是一层层向上级组件通知,直到通知到顶层组件,在我看来有点不太优雅,如果数据能统一在顶层组件里操作就好了。其次我的计划是写一个数据驱动的菜单组件,而不是像 Element Plus 需要手动拼装的,所以虽然我大致看懂了 Element Plus 菜单组件是怎么实现的,但在我自己实现的时候,还是有很大的不同,能参考的代码并不多。

这部分的开发总结,我可能会在以后单独写一篇文章详细说说,因为这部分也是整个方案中唯一的难点。

第三周,因为实现思路大致有了,所以开发上就没有太多的卡壳,最终结果也还不错,基本达到了我的需求。

同时因为组件完全可控,顺带解决了之前使用 Element Plus 菜单组件上无法解决的 bug ,比如当菜单收起时,弹出的悬浮菜单如果数量过多,超出屏幕高度,超出的部分就无法查看了,就像这样:

用1100天做一款通用的管理后台框架_表单_08

但是现在则会有滚动条,使用体验上更舒服。

用1100天做一款通用的管理后台框架_表单_09

回顾

让我们重新看下一开始的痛点是否都解决了么:

  • 以后会有 Ant Design Vue 版本么?会有 Naive UI 版本么?会有 …… 版本么?

虽然不会有,但可以自己动手,根据教程将默认的 Element Plus 替换成你想要的 UI 组件库就可以了

  • 我们公司/团队有一套内部的 UI 组件库,可以在 Fantastic-admin 里使用么?会和 Element Plus 有冲突么?

不会有冲突,现在可以彻底移除 Element Plus ,安装并使用自己的 UI 组件库

  • 我们有一些老项目希望迁移到 Fantastic-admin 上来,但 UI 组件库用的不是 Element Plus ,有什么办法么?

可以用 Fantastic-admin 源码先进行 UI 组件库的替换,之后再将老项目的业务代码逐部迁移

除了解决这些痛点,甚至还有新收获:

  • 帮助公司/企业打造视觉风格统一的产品,提高产品辨识度

大公司可能有不止一个项目团队,不同项目团队的技术偏好可能无法完全统一,导致开发的后台长得也千变万化。但即使在这种情况下,使用 Fantastic-admin 依旧可以保持整体视觉风格上的统一。

  • 近乎于 0 的上手成本

因为后台框架始终都只有一套,开发者不会因为切换 UI 组件库后,要重新了解后台框架的使用

  • 维护成本更低,产品生命周期更长

这一点是对我自己说的,不管未来会出现多少个新的 UI 组件库,我都不需要去新增一个版本进行单独维护;或者 Element Plus 如果有一天停止维护了,我的产品也不会因此进入了死亡倒计时

总结

文章写到这里,差不多就结束了,虽然阅读一遍可能只花了不到10分钟,但为了做成这件事,我大概从今年 6 月份就开始构思了,也是花了蛮多的精力,所以很感谢你的耐心。

当一款产品做到第 4 个年头,周围大部分同类产品都进入到半停更的状态,这一年里我经常思考如何延长产品的生命周期,如何让更多人来使用,而这篇文章就是对我自己今年的一个总结,也是一份答卷,希望大家能喜欢。

另外,Fantastic-admin V4.0 已经正式发布,感兴趣的朋友可以来看看,或许你的下一个项目,就可以用上了。

标签:天做,框架,Element,组件,菜单,UI,1100,后台,Plus
From: https://blog.51cto.com/u_16802720/12030201

相关文章

  • Android HandlerThread Post后延迟7秒才执行的原因及解决方案|如何提高Android后台线程
    在Android开发中,HandlerThread是用于处理后台线程任务的常见工具。然而,有时我们会遇到这样的问题:当任务通过HandlerThread的post方法发送后,任务的执行时间会出现明显的延迟,比如7秒的延迟才执行任务。本文将深入分析这种问题的成因,探讨可能的影响因素,并提供多种优化方案,帮助开发者解......
  • phpcms网站程序忘记了后台的登录密码怎么办
    如果你忘记了phpCMS网站后台的登录密码,可以通过以下两种方法来重置密码:方法1:通过数据库修改密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。登录数据库管理界面。找到用户表:通常表名为 v9_admin(具体表名可能有所不同,但通常带有前缀 v9_)。打开......
  • dedecms后台管理员密码忘记了该如何解决
    如果你忘记了织梦CMS(DedeCMS)的后台管理员密码,可以通过以下步骤来重置密码:方法1:通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。登录数据库管理界面。找到用户表:通常表名为 dede_admin(具体表名可能带有前缀,如 #@__dede_admin)。......
  • PbootCms忘记后台管理员密码这样找回
    如果你忘记了PbootCMS后台管理员的密码,可以通过以下步骤来重置密码:方法1:使用官方提供的密码重置工具下载密码重置工具:下载官方提供的密码重置工具 resetpw.php。将 resetpw.php 文件上传到网站根目录。访问重置工具:在浏览器中访问 http://[您的域名]/resetpw.......
  • 网站后台管理员密码找回
    找回网站后台管理员密码通常有几种常见的方法,具体取决于你使用的CMS系统(如WordPress、DedeCMS、EmpireCMS等)。下面是一些通用的方法来帮助你找回或重置网站后台管理员密码:1.使用找回密码功能许多CMS系统都有内置的“忘记密码”功能,可以通过注册时使用的电子邮件地址或手机号码......
  • 帝国cms忘记了后台密码怎么办
    如果你忘记了帝国CMS(EmpireCMS)的后台管理员密码,可以通过以下步骤来重置密码:方法1:通过数据库重置密码登录数据库:使用数据库管理工具(如phpMyAdmin)连接到你的数据库。登录数据库管理界面。找到用户表:通常表名为 phome_enewsuser(具体表名可能有所不同)。打开表 phom......
  • dedecms后台管理员帐号密码忘记了怎么办
    如果你忘记了DedeCMS(织梦CMS)后台管理员账号的密码,可以通过以下几种方法来重置密码:方法一:使用插件重置密码下载并上传插件下载一个用于重置密码的插件。将插件文件(例如radminpass.php)上传到网站根目录下。访问插件页面在浏览器中访问 http://你的域名/radminpass.php......
  • 怎么找回苹果cms后台管理员密码_苹果cms后台密码
    如果你忘记了苹果CMS,后台管理员的密码,可以通过直接修改数据库中的密码记录来重置密码。以下是具体步骤:步骤:连接数据库使用数据库管理工具(如phpMyAdmin)连接到你的数据库。登录到你的数据库管理系统。定位管理员表找到存储管理员信息的表,通常情况下,苹果CMS的管理员信......
  • 织梦dedecms 忘记管理员后台密码的解决技巧
    如果你忘记了织梦Dedecms的管理员后台密码,可以通过以下几种方法来重置密码:方法一:直接修改数据库登录MySQL数据库管理工具(如phpMyAdmin)。定位到Dedecms数据库,找到表dede_admin。浏览数据,找到管理员账户(通常是userid='admin')。修改密码:对于Dedecms5.3及以上版本,密码......
  • 织梦CMS 忘记后台管理员密码的一种解决方法
    如果你忘记了织梦CMS(Dedecms)的后台管理员密码,并且拥有对MySQL数据库的操作权限,可以按照以下步骤重置密码:步骤1:登录MySQL数据库打开MySQL客户端,如phpMyAdmin或命令行工具。登录MySQL数据库:sql mysql-u用户名-p输入密码后登录。步骤2:选择对应的数据......