老板要求用Nextjs+Shadcn写一个Ruoyi管理后台架子,支持KeepAlive+Tab窗口,主打一个国际接轨

文章 2小时前 juejinhot
1 0

为啥就换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

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...