为啥就换Shadcn了
因为Shadcn太火了,不少大大小小的火出圈的ai项目,就是基于Shadcn搭建的,比如assistant-ui,为了与时俱进,与国际接轨,要求我必须整出来一套对接好Ruoyi-pro,支持KeepAlive的管理后台架子,准备稳步迭代部分旧有项目和开发新项目,主动迎接ai代码智能体的时代,为团队插上ai赋能翅膀
反正闲着也是闲着,那就整吧~
shadcn是真“一用一个不吱声”
看是该给的都给了,实则要啥没啥,简直“如给”
但不用慌,这回就到了体现React社区强大之处的时候了~
我想整个Tree,有么?
- 社区:rc-tree
- 需求:因为ruoyi中有几处需要tree的地方,比如用户管理
- 演示:
开发心得:
主要是定制上,demo的样式没法用,定制起来些许阻碍,不过好在都有办法解决,花了一天整合出了Shacn版本,可以为了道友们节省一些精力。
我想整个table,有么?
- 社区:tanstack table
- 需求:不用问了吧,必须得有的,而且还得支持折叠,选中,翻页等功能
- 演示:
开发心得:当开发折叠的时候,发现折叠打开的时候要,下方的数据会被挤到下一页的问题,一时不知怎么解决,翻了文档,居然真有解决办法,很轻松就解决了,从这一点就能看出来,这个库有多神,table是玩明白了,面面俱到。
我想整个表单,有么?
- 社区:react-hook-form
- 需求:不用问了吧,表单太关键了
- 演示:
我想整个toast,有么?
- 社区:sonner
- 需求:不用说了,基本需求
- 演示:
我想整个路由导航进度条,有么?
- 社区:bprogress
- 需求:Nextjs的路由跳转的时候,避免不了加载过程,有些时候网络比较慢,那么点击导航的时候看起来像没反应,体验不好,加个进度条,提示一下页面正在加载。
- 演示:
我想整个路由切换动画,有么?
- 社区:motion
- 需求:路由切换的时候,最好给个过渡动画,不然切换太突兀,观感不好,需要改善一下体验
- 演示:
我想整个引导教程,有么?
- 社区:driverjs
- 需求: 引导教程
- 演示:
我想整个icon,有么?
- 社区:iconify
- 需求:简单好用,海量icon,无需引入太多,仅传入一个icon字符即可。
- 演示:
keep alive:全网你就找吧,Nextjs的app路由的的keepalive,我这个是独一份解决方案
三步骤,一步一登梯
- 第一步:keepAlve,
- 第二步:tab导航,因为没有tab导航的keepalive就是吃酱牛肉不配蒜酱啊,没有灵魂,现实来看就是,你得让keepAlive有生命周期,光靠菜单,就会永远缓存,得可以关闭,tab栏就是给你管理keepAlive用的
- 第三步:useActive-可以监听切换窗口的hook,这步看似不起眼,但是实则才是能否完整keep alive的验金石
方案介绍
本方案为 Next.js 提供了灵活的页面缓存(KeepAlive)能力,适用于多标签页、页面状态保留等复杂场景。
主要文件说明
-
keep-alive:顶层组件,提供全局 KeepAlive 能力
-
keep-alive-sign:标记需要缓存的页面或组件
-
keep-alive-slot:定向渲染插槽,实现精准渲染
-
keep-alive-route:内部业务核心组成,通常无需关注
使用方法
第一步:在顶层 Layout 包裹 KeepAlive
在页面的 layout 组件(如管理后台 dashboard 的 layout.tsx)中包裹 KeepAlive:
<KeepAlive>{children}</KeepAlive>
第二步:在需要缓存的页面中使用 KeepAliveSign
// 客户端渲染,并且需要缓存的组件
const MenuView = () => {
return <div>菜单页面</div>;
};
export default function MenuPage() {
const customId = "自定义id";
return (
<div>
{/* 其他组件,可为服务端或客户端组件。key 用于复杂场景避免渲染错位 */}
<KeepAliveSign key={customId} routeId={customId} ClientView={MenuView}>
...
</KeepAliveSign>
</div>
);
}
-
routeId:路由唯一标识,必须唯一,用于标记缓存页面
-
key:唯一标识,建议复杂场景下使用,避免渲染错位
-
ClientView:需要被缓存的客户端组件
第三步:在 KeepAliveSign 内使用 KeepAliveSlot 实现定点渲染
与服务端组件组合渲染时,KeepAliveSlot 可实现精准定位:
export default function MenuPage() {
const customId = "自定义id";
return (
<div>
<KeepAliveSign key={customId} routeId={customId} ClientView={MenuView}>
{/* 其他组件,可为服务端或客户端组件 */}
<KeepAliveSlot id={customId} />
{/* 其他组件,可为服务端或客户端组件 */}
</KeepAliveSign>
</div>
);
}
- id:需与 KeepAliveSign 的 routeId 保持一致,无需设置不同值
KeepAlive
Tab导航,拖拽,缓存
useActive
路由增强:没有配置的约定式路由,就剩约定了,没有大用处
Next.js 原生采用约定式、基于文件系统的路由机制。
那为什么还需要额外配置路由?
主要是为了满足更复杂的业务需求,例如:
- 支持 KeepAlive 页面缓存
- 多标签页(Tab)窗口
- 菜单权限控制
- 函数式路由跳转
- 自动补全路由 path,减少重复配置
- 以及其他路由元信息的灵活扩展
本方案通过配置化的数据结构和统一的 routerHelper 工具,将所有与路由相关的业务接口集中管理,极大简化了路由与接口的维护流程,提升了项目的可扩展性和长期可维护性。
主要文件说明
- router-name:为每个路由分配唯一标识
- routes-config:配置路由的基本信息
- router-provider:增强路由能力,如自动补全 path、提供函数式跳转等
- router-type:路由相关的类型定义
如何创建一个新路由
第一步:在 router-name.ts 中添加路由名称
export enum ROUTE_NAME {
// ... 其他路由名称
user,
}
第二步:在 routes-config.ts 中添加路由配置
import { ROUTE_NAME } from "./router-name";
import User from "@/pages/User"; // 假设你有一个User页面组件
const routesConfig = {
user: {
id: "user",
meta: {
title: "common:UserPageTitle",
icon: "FundProjectionScreenOutlined",
},
},
};
export default routesConfig;
第三步:路由跳转
可在全局任意位置通过函数方式跳转,组件外也能直接调用:
routerHelper.jumpTo(ROUTE_NAME.dashboard);
ruoyi对接
登录
角色管理
用户管理
菜单管理
这个项目的魂,是贯彻实践了MVC模式
看到这个矩阵了么,我实现纯前端的Antd版本,也实现了Nextjs的Shacn版本,最难的对角线完成了,足以说明MVC模式的强大,“一套代码,多套组件库,支持纯前端和Nextjs模式”,有没有很熟悉,类似一套代码,多端运行
我这个是跨中跨,跨的平方,这是MVC模式,或者准确是Flux模式的真诚实践,不敢说最佳吧,真诚肯定有了,我已经用我这套模式用在我的实际工作中两年了,给我带来了解放。
现在我的许多业务,完全托管给Ai了
所以说,项目好好写,业务能分层,有一个清晰统一的套路,是对接ai赋能的关键。
你不信?我也不想去自证啥,只能说,你不妨试试,没什么损失,不需要你肯定我什么,但凡能帮你一点,就证明了价值传导给你了,那么就算可以了,你要是还能成为更好的自己,继续传递价值,那就是圆满了,非常好了,我向你致敬,同志。
为啥要用Shadcn,相比Antd,mui又如何?
这个问题太难回答了,我的观点是当下无脑选shadcn,因为最契合现在Ai代码智能体时代、
用过这三个组件库的我,怎么描述我对三个组件库的直观感受呢?em~~就像乐高
Antd
Mui
Shadcn
这三张图就是我对这三大组件库的感受,shadcn结合原子化样式+足够碎,使其有着更好的组合空间,天花板很高,并且结合ai,可以很容易生成出来我们想要的东西,
项目地址和预览地址
还有好多功能细节,玩法技巧,这里就不作赘述,有兴趣的朋友可以自行探索。
预览地址
源码已经开源,java用的就是Ruoyi芋道作为后端例子,有兴趣的可以自行运行起来。
前端是一个Monorepo,放在了根目录下的frontend文件夹下,直接运行npm run start
即可运行。
项目地址
什么你想要Antd版本,有的,兄弟,包有的!
预览
题外话
我写这个项目,不是为了证明我技术多牛批,也不是证明我文章写的有多好,而是我想把前端搬砖这件事情,变成他本来该有的样子。
-
别太纠结用不用,还是用什么去做状态管理
-
也不要反复辩论,用react还是vue,哪个好了
我们应该达成共识,基本的共识,我们在写的是什么?是简单的代码字符么?是你抖机灵搞抽象说的元子或是寂寞么?都不是的
我们在写的是我们的“道”,每个编程人都应有自己的码道。
那么回归事情的本质,我们为啥用状态管理,是因为我们要实现业务分层,简单说就是MVC,准确说flux模式,目的就是业务看起来清晰,维护轻松愉快,减轻压力。
那么纠结react还是vue,取决于你自己的感受,当你想表达自己的“道”,那么更纯粹,更贴近直觉的,更贴近编程语言习惯,便是最舒服,最自然,我选择React
我做游戏多年转行做的前端,开始写Vue,实话实说,一头雾水当时,知识点好多,但是没干多久,我就换React了,一下就行云流水了,只有有编程功力,那么写React就相当顺手。
还有咱们得说一个事实,大厂的编程人是要相对有实力的,他们对编程的理解和品味,应该是相对不错的,大厂普遍选择React,自然也印证了,在诠释“道”的方式上,React更被青睐。
当然你也可以说,我说这么多,MVC分层到底怎么是魂了,到底怎么厉害了?
我没必要去自证这些了,我就算说的天花乱坠,该不接受的还是不不接受,你叫不醒。
但是我还是坚持不懈的,傻傻的去实践,我目的是让这浮躁的,充满噪音的前端圈子,带去一点安静的慢力量,
慢下来吧,同志们,带我们去未来的不一定非得是钱,有个强大平静的心灵也是可以的。
技术支持
欢迎加入「闲 D 岛 🏝️」技术交流群,这里有大厂工程师、独立开发者、外包团队和热心小伙伴,氛围纯净,技术交流活跃,期待你的加入!
- 闲 D 岛 1 群(500+ 人):551406017
- 闲 D 岛 2 群:1002504812
转载请注明:老板要求用Nextjs+Shadcn写一个Ruoyi管理后台架子,支持KeepAlive+Tab窗口,主打一个国际接轨 | 程序员导航网