|
|
# RuoYi-Vue 前端架构分析
|
|
|
|
|
|
> **项目版本**: 3.8.0 | **技术栈**: Vue 2.6.12 + Element UI 2.15.6 + Vuex 3.6 + Vue Router 3.4.9
|
|
|
> **构建工具**: Vue CLI 4.4.6 | **描述**: 摸金分析系统
|
|
|
> **分析日期**: 2026-06-28
|
|
|
|
|
|
---
|
|
|
|
|
|
## 1. 组件结构分析
|
|
|
|
|
|
### 1.1 组件树图(ASCII)
|
|
|
|
|
|
```
|
|
|
src/
|
|
|
├── components/ # 全局通用组件(22 个组件组)
|
|
|
│ ├── Breadcrumb/ # ── 面包屑导航
|
|
|
│ ├── Crontab/ # ── Cron 表达式生成器(9 个子组件)
|
|
|
│ │ ├── day.vue / hour.vue / min.vue # 时间维度选择
|
|
|
│ │ ├── month.vue / week.vue / year.vue
|
|
|
│ │ ├── second.vue / result.vue / index.vue
|
|
|
│ ├── DictData/ # ── 字典数据管理器(JS 模块)
|
|
|
│ ├── DictTag/ # ── 字典标签渲染
|
|
|
│ ├── Editor/ # ── 富文本编辑器(Quill)
|
|
|
│ ├── FileUpload/ # ── 文件上传
|
|
|
│ ├── Hamburger/ # ── 汉堡菜单按钮
|
|
|
│ ├── HeaderSearch/ # ── 头部搜索(Fuse.js)
|
|
|
│ ├── IconSelect/ # ── SVG 图标选择器
|
|
|
│ ├── ImagePreview/ # ── 图片预览
|
|
|
│ ├── ImageUpload/ # ── 图片上传
|
|
|
│ ├── Kdialog/ # ── K 线对话框(业务组件)
|
|
|
│ ├── NegativeDialog/ # ── 涨跌停对话框(业务组件)
|
|
|
│ ├── Pagination/ # ── 分页器
|
|
|
│ ├── PanThumb/ # ── 全景缩略图
|
|
|
│ ├── ParentView/ # ── 父级视图占位
|
|
|
│ ├── RightPanel/ # ── 右侧面板
|
|
|
│ ├── RightToolbar/ # ── 右侧工具栏
|
|
|
│ ├── RuoYi/ # ── 外部链接(Doc / Git)
|
|
|
│ ├── Screenfull/ # ── 全屏切换
|
|
|
│ ├── SizeSelect/ # ── 组件尺寸选择
|
|
|
│ ├── SvgIcon/ # ── SVG 图标封装
|
|
|
│ ├── ThemePicker/ # ── 主题选择器
|
|
|
│ ├── TopNav/ # ── 顶部导航
|
|
|
│ ├── TrendStocksDialog/ # ── 板块趋势对话框(业务)
|
|
|
│ └── iFrame/ # ── 内嵌 iframe
|
|
|
│
|
|
|
├── layout/ # 布局框架
|
|
|
│ ├── index.vue # ── 主布局容器
|
|
|
│ ├── components/
|
|
|
│ │ ├── AppMain.vue # ── 主内容区(含 keep-alive)
|
|
|
│ │ ├── Navbar.vue # ── 顶部导航栏
|
|
|
│ │ ├── Sidebar/ # ── 侧边栏
|
|
|
│ │ │ ├── index.vue / SidebarItem.vue / Item.vue / Link.vue / Logo.vue
|
|
|
│ │ ├── TagsView/ # ── 标签页视图
|
|
|
│ │ │ ├── index.vue / ScrollPane.vue
|
|
|
│ │ ├── Settings/ # ── 系统设置面板
|
|
|
│ │ └── InnerLink/ # ── 内部链接
|
|
|
│ └── mixin/ResizeHandler.js # ── 响应式 Mixin
|
|
|
│
|
|
|
├── views/ # 页面视图(按业务模块)
|
|
|
│ ├── dashboard/ # ── 仪表盘(5 个图表组件)
|
|
|
│ ├── system/ # ── 系统管理(8 个子模块)
|
|
|
│ ├── booksystem/ # ── 账本系统(6 个子模块)
|
|
|
│ ├── stocksystem/ # ── 股票系统(8 个子模块)
|
|
|
│ ├── monitor/ # ── 系统监控(7 个子模块)
|
|
|
│ ├── tool/ # ── 系统工具(代码生成等)
|
|
|
│ ├── error/ # ── 错误页面
|
|
|
│ ├── login.vue / register.vue # ── 认证页面
|
|
|
│ └── index.vue # ── 首页
|
|
|
```
|
|
|
|
|
|
### 1.2 分类统计
|
|
|
|
|
|
| 分类 | 组件/模块数量 | 说明 |
|
|
|
|------|-------------|------|
|
|
|
| **通用 UI 组件** | 10 | Breadcrumb, Pagination, SvgIcon, Hamburger, Screenfull, SizeSelect, ThemePicker, PanThumb, ParentView, iFrame |
|
|
|
| **业务组件** | 4 | Kdialog, NegativeDialog, TrendStocksDialog, RightToolbar |
|
|
|
| **功能组件** | 7 | Crontab(9), DictTag, DictData, Editor, FileUpload, ImageUpload, ImagePreview, IconSelect, HeaderSearch |
|
|
|
| **布局组件** | 8 | Layout, AppMain, Navbar, Sidebar(5), TagsView(2), Settings, InnerLink |
|
|
|
| **视图模块** | 6 大模块 | dashboard, system, booksystem, stocksystem, monitor, tool |
|
|
|
| **视图页面总数** | ~40 个 | 包含子页面和嵌套路由页面 |
|
|
|
|
|
|
### 1.3 组件复用程度分析
|
|
|
|
|
|
**高复用组件**(被全局注册或在多个视图中引用):
|
|
|
- `Pagination` — 几乎所有列表页面
|
|
|
- `DictTag` — 所有涉及字典展示的页面
|
|
|
- `RightToolbar` — 所有 CRUD 列表页
|
|
|
- `Editor` / `FileUpload` / `ImageUpload` — 表单页面
|
|
|
- `Breadcrumb` — 布局层全局使用
|
|
|
- `SvgIcon` — 全局图标渲染基础组件
|
|
|
|
|
|
**中复用组件**(特定业务场景):
|
|
|
- `Crontab` — 仅定时任务模块
|
|
|
- `Kdialog` / `TrendStocksDialog` / `NegativeDialog` — 股票业务模块
|
|
|
- `HeaderSearch` — 仅 Navbar 使用
|
|
|
|
|
|
**低复用组件**(单一职责或一次性使用):
|
|
|
- `PanThumb` — 仅用户个人资料页
|
|
|
- `RightPanel` — 仅布局设置入口
|
|
|
- `RuoYi/Doc` / `RuoYi/Git` — 外部链接
|
|
|
|
|
|
### 1.4 组件职责分析
|
|
|
|
|
|
| 组件 | 职责单一性 | 评价 |
|
|
|
|------|----------|------|
|
|
|
| Crontab | 一般 | 9 个子组件拆分合理,但耦合度较高 |
|
|
|
| Kdialog / NegativeDialog | 低 | 业务逻辑与 UI 混合,体积过大 |
|
|
|
| Dashboard 图表组件 | 好 | 每个图表独立文件,职责清晰 |
|
|
|
| Layout 子组件 | 好 | Sidebar、Navbar、TagsView 分离清晰 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 2. 路由与权限控制
|
|
|
|
|
|
### 2.1 路由结构图
|
|
|
|
|
|
```
|
|
|
路由系统
|
|
|
├── 静态路由 (constantRoutes) — 始终可访问
|
|
|
│ ├── /redirect/:path — 重定向页
|
|
|
│ ├── /login — 登录页
|
|
|
│ ├── /register — 注册页
|
|
|
│ ├── /404 — 404 错误页
|
|
|
│ ├── /401 — 401 错误页
|
|
|
│ ├── / (首页) — Dashboard
|
|
|
│ └── /user/profile — 个人中心
|
|
|
│
|
|
|
├── 动态路由 (dynamicRoutes) — 按权限加载
|
|
|
│ ├── /system/user-auth/role/:userId — 分配角色 [system:user:edit]
|
|
|
│ ├── /system/role-auth/user/:roleId — 分配用户 [system:role:edit]
|
|
|
│ ├── /system/dict-data/index/:dictId — 字典数据 [system:dict:list]
|
|
|
│ ├── /monitor/job-log — 调度日志 [monitor:job:list]
|
|
|
│ └── /tool/gen-edit — 修改生成配置 [tool:gen:edit]
|
|
|
│
|
|
|
└── 服务端路由 — 登录后从后端获取
|
|
|
├── filterAsyncRouter() ── 转换为组件对象
|
|
|
├── filterDynamicRoutes() ── 权限过滤
|
|
|
└── router.addRoutes() ── 动态注册
|
|
|
```
|
|
|
|
|
|
### 2.2 权限加载流程
|
|
|
|
|
|
```
|
|
|
用户登录
|
|
|
│
|
|
|
├─ 1. 输入用户名/密码/验证码
|
|
|
├─ 2. 调用 POST /login → 获取 token → 存入 Cookie (Admin-Token)
|
|
|
├─ 3. 路由守卫 beforeEach 拦截
|
|
|
│ │
|
|
|
│ ├─ 有 token ? ──NO──→ 跳转 /login
|
|
|
│ │ │
|
|
|
│ │ YES
|
|
|
│ │ │
|
|
|
│ │ ├─ roles.length === 0 ? ──NO──→ next()
|
|
|
│ │ │ │
|
|
|
│ │ │ YES
|
|
|
│ │ │ │
|
|
|
│ │ │ ├─ GetInfo() → 获取用户信息(roles + permissions)
|
|
|
│ │ │ │
|
|
|
│ │ │ └─ GenerateRoutes() → 请求 /getRouters
|
|
|
│ │ │ │
|
|
|
│ │ │ ├─ filterAsyncRouter() → 字符串转组件
|
|
|
│ │ │ ├─ filterDynamicRoutes() → 权限过滤
|
|
|
│ │ │ └─ router.addRoutes() → 注册路由
|
|
|
│ │ │
|
|
|
│ │ └─ next({ ...to, replace: true }) → 重新导航
|
|
|
│ │
|
|
|
│ └─ 无 token → 白名单 ? ──YES──→ next()
|
|
|
│ │
|
|
|
│ NO
|
|
|
│ │
|
|
|
│ 跳转 /login?redirect=xxx
|
|
|
│
|
|
|
└─ 4. 页面渲染 → 动态菜单展示
|
|
|
```
|
|
|
|
|
|
### 2.3 权限控制机制
|
|
|
|
|
|
项目采用 **三层权限控制**:
|
|
|
|
|
|
| 层级 | 实现方式 | 代码位置 |
|
|
|
|------|---------|---------|
|
|
|
| **路由级** | 路由守卫 + 服务端返回菜单 | `src/permission.js` + `src/store/modules/permission.js` |
|
|
|
| **页面级** | `v-hasPermi` / `v-hasRole` 指令 | `src/directive/permission/` |
|
|
|
| **按钮级** | `$auth.hasPermi()` / `$auth.hasRole()` | `src/plugins/auth.js` |
|
|
|
|
|
|
**权限标识格式**:`模块:资源:操作`(如 `system:user:add`)
|
|
|
**超级权限**:`*:*:*`(拥有所有权限)
|
|
|
**超级角色**:`admin`(拥有所有角色权限)
|
|
|
|
|
|
### 2.4 路由懒加载
|
|
|
|
|
|
```javascript
|
|
|
// 开发环境:使用 require 实现
|
|
|
if (process.env.NODE_ENV === 'development') {
|
|
|
return (resolve) => require([`@/views/${view}`], resolve)
|
|
|
}
|
|
|
// 生产环境:使用 import 实现
|
|
|
else {
|
|
|
return () => import(`@/views/${view}`)
|
|
|
}
|
|
|
```
|
|
|
|
|
|
---
|
|
|
|
|
|
## 3. 状态管理分析
|
|
|
|
|
|
### 3.1 Vuex 模块图
|
|
|
|
|
|
```
|
|
|
Vuex Store
|
|
|
├── getters.js # 统一访问入口
|
|
|
│ ├── sidebar, size, device → state.app
|
|
|
│ ├── visitedViews, cachedViews → state.tagsView
|
|
|
│ ├── token, avatar, name, roles → state.user
|
|
|
│ └── permission_routes, topbarRouters, sidebarRouters → state.permission
|
|
|
│
|
|
|
├── modules/app.js # 应用级状态
|
|
|
│ ├── sidebar { opened, withoutAnimation }
|
|
|
│ ├── device ('desktop' | 'mobile')
|
|
|
│ └── size ('medium' | 'small' | 'mini')
|
|
|
│ └── 持久化:Cookies (sidebarStatus, size)
|
|
|
│
|
|
|
├── modules/user.js # 用户状态
|
|
|
│ ├── token, name, avatar
|
|
|
│ ├── roles: string[]
|
|
|
│ ├── permissions: string[]
|
|
|
│ └── Actions: Login, GetInfo, LogOut, FedLogOut
|
|
|
│ └── 持久化:Cookies (Admin-Token)
|
|
|
│
|
|
|
├── modules/permission.js # 权限/路由状态
|
|
|
│ ├── routes, addRoutes — 完整路由表 / 动态路由
|
|
|
│ ├── defaultRoutes, topbarRouters, sidebarRouters
|
|
|
│ └── Actions: GenerateRoutes
|
|
|
│
|
|
|
├── modules/tagsView.js # 标签页状态
|
|
|
│ ├── visitedViews: [] — 已访问的标签页
|
|
|
│ ├── cachedViews: [] — 被 keep-alive 缓存的页面
|
|
|
│ └── Actions: addView, delView, delOthersViews, delAllViews,
|
|
|
│ delRightTags, delLeftTags
|
|
|
│
|
|
|
└── modules/settings.js # 系统设置状态
|
|
|
├── theme, sideTheme, showSettings
|
|
|
├── topNav, tagsView, fixedHeader, sidebarLogo, dynamicTitle
|
|
|
└── 持久化:localStorage ('layout-setting')
|
|
|
```
|
|
|
|
|
|
### 3.2 数据流向
|
|
|
|
|
|
```
|
|
|
┌──────────────┐
|
|
|
│ Vue 组件 │
|
|
|
└──────┬───────┘
|
|
|
│ dispatch
|
|
|
▼
|
|
|
┌──────────────┐
|
|
|
│ Actions │ ──→ 异步操作(API 调用)
|
|
|
└──────┬───────┘
|
|
|
│ commit
|
|
|
▼
|
|
|
┌──────────────┐
|
|
|
│ Mutations │ ──→ 同步修改 state
|
|
|
└──────┬───────┘
|
|
|
│
|
|
|
▼
|
|
|
┌──────────────┐
|
|
|
│ State │ ──→ 响应式数据
|
|
|
└──────┬───────┘
|
|
|
│
|
|
|
┌──────┴───────┐
|
|
|
│ Getters │ ──→ 计算属性
|
|
|
└──────┬───────┘
|
|
|
│
|
|
|
┌──────┴───────┐
|
|
|
│ Vue 组件 │ ←── 重新渲染
|
|
|
└──────────────┘
|
|
|
```
|
|
|
|
|
|
### 3.3 状态持久化
|
|
|
|
|
|
| 状态 | 存储方式 | 键名 | 说明 |
|
|
|
|------|---------|------|------|
|
|
|
| 用户 Token | Cookie | `Admin-Token` | 会话认证 |
|
|
|
| 侧边栏状态 | Cookie | `sidebarStatus` | 展开/折叠 |
|
|
|
| 组件尺寸 | Cookie | `size` | Element UI 默认尺寸 |
|
|
|
| 布局设置 | localStorage | `layout-setting` | JSON 对象(主题、顶栏、标签页等) |
|
|
|
|
|
|
> **注意**:Vuex 本身无持久化插件,数据分散在 Cookie 和 localStorage 中手动读写。
|
|
|
|
|
|
---
|
|
|
|
|
|
## 4. API 调用层
|
|
|
|
|
|
### 4.1 Axios 封装架构
|
|
|
|
|
|
```
|
|
|
src/api/ # API 模块目录
|
|
|
├── booksystem/ # ── 账本系统 API(6 个文件)
|
|
|
├── stocksystem/ # ── 股票系统 API(9 个文件)
|
|
|
├── system/ # ── 系统管理 API(7 个文件 + dict 子目录)
|
|
|
├── monitor/ # ── 系统监控 API(7 个文件)
|
|
|
├── tool/ # ── 系统工具 API
|
|
|
├── login.js # ── 登录/获取信息/退出
|
|
|
├── menu.js # ── 获取动态路由
|
|
|
└── index.js # ── 通用 API
|
|
|
|
|
|
src/utils/request.js # Axios 实例封装
|
|
|
├── baseURL: process.env.VUE_APP_BASE_API
|
|
|
├── timeout: 60000ms (60秒)
|
|
|
├── Content-Type: application/json;charset=utf-8
|
|
|
└── download() 方法 # ── 文件下载封装
|
|
|
```
|
|
|
|
|
|
### 4.2 拦截器实现
|
|
|
|
|
|
#### 请求拦截器(Request Interceptor)
|
|
|
|
|
|
```
|
|
|
请求发出
|
|
|
│
|
|
|
├─ 1. 检查是否需要 token(config.headers.isToken === false 可跳过)
|
|
|
├─ 2. 自动添加 Authorization: Bearer {token}
|
|
|
├─ 3. GET 请求 params 序列化(tansParams 处理)
|
|
|
│ └─ 将 ?a=1&b=2 拼接到 URL,清空 config.params
|
|
|
└─ 4. 发送请求
|
|
|
```
|
|
|
|
|
|
#### 响应拦截器(Response Interceptor)
|
|
|
|
|
|
```
|
|
|
收到响应
|
|
|
│
|
|
|
├─ 解析业务状态码 res.data.code
|
|
|
│
|
|
|
├─ code === 401 → MessageBox 弹窗 → 确认后 LogOut → 跳首页
|
|
|
├─ code === 500 → Message.error(msg) → Promise.reject
|
|
|
├─ code !== 200 → Notification.error({ title: msg }) → Promise.reject
|
|
|
├─ code === 200 → 返回 res.data
|
|
|
│
|
|
|
└─ HTTP 错误捕获(error)
|
|
|
├─ Network Error → "后端接口连接异常"
|
|
|
├─ timeout → "系统接口请求超时"
|
|
|
├─ status code 4xx/5xx → "系统接口 XXX 异常"
|
|
|
└─ Message.error(message, duration: 5s)
|
|
|
```
|
|
|
|
|
|
### 4.3 错误处理机制
|
|
|
|
|
|
| 错误类型 | 处理方式 | 用户体验 |
|
|
|
|---------|---------|---------|
|
|
|
| 401 未授权 | 弹窗确认 → 退出登录 | 强提醒,需用户操作 |
|
|
|
| 500 服务端错误 | Message 提示 | 轻量提示,自动消失 |
|
|
|
| 其他业务错误 | Notification 通知 | 右上角通知 |
|
|
|
| 网络异常 | Message 提示(5 秒) | 长时提示 |
|
|
|
| 请求超时 | Message 提示(5 秒) | 长时提示 |
|
|
|
| 下载失败 | 解析 blob 中的 JSON 错误信息 | 自动处理登录态失效 |
|
|
|
|
|
|
### 4.4 错误码映射
|
|
|
|
|
|
通过 `src/utils/errorCode.js` 实现业务码到提示文本的映射,支持:
|
|
|
- 预定义错误码映射
|
|
|
- 默认兜底文本
|
|
|
- 服务端返回的自定义 msg
|
|
|
|
|
|
---
|
|
|
|
|
|
## 5. 存在的问题
|
|
|
|
|
|
### 5.1 问题清单
|
|
|
|
|
|
| # | 问题 | 影响 | 严重程度 |
|
|
|
|---|------|------|---------|
|
|
|
| 1 | **Vue 2 + Vue CLI 技术栈老化**:Vue 2 已于 2023 年底停止官方维护,Vue Router 3、Vuex 3、Vue CLI 4 均为旧版本,存在安全风险且无法使用 Composition API 等现代特性 | 长期维护成本高,无法使用新生态,第三方库兼容性逐步下降 | 🔴 高 |
|
|
|
| 2 | **权限逻辑重复实现**:权限校验在 4 个位置分别实现(`plugins/auth.js`、`utils/permission.js`、`directive/permission/hasPermi.js`、`directive/permission/hasRole.js`),逻辑高度重复但存在细微差异,如超级权限标识散落在各处 | 维护困难,修改权限规则需同时修改多处,易遗漏导致权限漏洞 | 🟡 中 |
|
|
|
| 3 | **状态持久化分散且不统一**:Token 存 Cookie、sidebar 状态存 Cookie、布局设置存 localStorage,手动读写无统一管理,无 vuex-persistedstate 等插件,刷新后部分状态可能不一致 | 状态管理混乱,调试困难,存在不同步风险 | 🟡 中 |
|
|
|
| 4 | **业务组件与通用组件混放**:`Kdialog`、`TrendStocksDialog`、`NegativeDialog` 等强业务耦合组件放在 `src/components/` 通用组件目录,且通过全局注册加载,增加了首屏包体积 | 首屏加载变慢,通用组件库被业务代码污染,不利于复用 | 🟡 中 |
|
|
|
| 5 | **视图页面高度模板化**:`system/`、`booksystem/`、`stocksystem/` 下的 CRUD 页面结构高度相似(搜索表单 + 表格 + 分页 + 弹窗),但未抽取为可配置的高阶组件或 Schema 驱动表单 | 代码冗余度高,新增 CRUD 页面工作量大,修改通用逻辑需改多个文件 | 🟡 中 |
|
|
|
| 6 | **生产/开发环境使用不同的懒加载方式**:开发环境用 `require()`,生产环境用 `import()`,两份逻辑增加了维护复杂度,且开发环境无法享受代码分割的优化效果 | 开发构建产物大,热更新慢,行为不一致可能导致线上问题 | 🟢 低 |
|
|
|
| 7 | **响应拦截器中 401 处理使用同步 location.href 跳转**:`location.href = '/index'` 是硬跳转,绕过了 Vue Router 的导航守卫和状态清理流程 | 可能导致 Vuex 状态未完全清理、标签页数据残留 | 🟢 低 |
|
|
|
| 8 | **缺少统一的请求重试机制**:网络波动或后端短暂不可用时,所有请求直接失败,无自动重试策略 | 用户体验下降,偶发性网络问题导致操作失败 | 🟢 低 |
|
|
|
|
|
|
### 5.2 优化建议
|
|
|
|
|
|
| 优先级 | 建议 | 预期收益 |
|
|
|
|--------|------|---------|
|
|
|
| P0 | 规划升级至 Vue 3 + Vite + Pinia | 获得性能提升、Composition API、更好的类型支持 |
|
|
|
| P1 | 抽取统一的权限校验核心模块,消除重复代码 | 降低维护成本,消除权限逻辑不一致风险 |
|
|
|
| P1 | 引入 vuex-persistedstate 或自定义统一持久化层 | 状态管理规范化,减少手动读写 Cookie/LocalStorage |
|
|
|
| P2 | 将业务组件移至对应业务模块目录,或采用按需异步加载 | 减少首屏包体积,保持通用组件库纯净 |
|
|
|
| P2 | 抽取 CRUD 页面为 Schema 驱动的高阶组件 | 减少 60%+ 的 CRUD 页面代码量 |
|
|
|
| P3 | 统一开发/生产的组件加载方式 | 简化代码,提升开发体验 |
|
|
|
| P3 | 401 处理改用 router.replace() 代替 location.href | 状态清理更完整,避免残留数据 |
|
|
|
| P3 | 在 request.js 中添加可配置的重试机制 | 提升网络不稳定场景下的用户体验 |
|
|
|
|
|
|
---
|
|
|
|
|
|
## 附录:技术栈概览
|
|
|
|
|
|
| 类别 | 技术 | 版本 |
|
|
|
|------|------|------|
|
|
|
| 核心框架 | Vue | 2.6.12 |
|
|
|
| UI 框架 | Element UI | 2.15.6 |
|
|
|
| 路由 | Vue Router | 3.4.9 |
|
|
|
| 状态管理 | Vuex | 3.6.0 |
|
|
|
| HTTP 客户端 | Axios | 0.24.0 |
|
|
|
| 构建工具 | Vue CLI | 4.4.6 |
|
|
|
| CSS 预处理器 | Sass | 1.32.13 |
|
|
|
| 图表库 | ECharts | 4.9.0 |
|
|
|
| 富文本 | Quill | 1.3.7 |
|
|
|
| 代码高亮 | highlight.js | 9.18.5 |
|
|
|
| 拖拽排序 | SortableJS / vuedraggable | 1.10.2 / 2.24.3 |
|
|
|
| SVG 图标 | svg-sprite-loader | 5.1.1 |
|
|
|
| 加密 | jsencrypt | 3.2.1 |
|
|
|
| 进度条 | NProgress | 0.2.0 |
|
|
|
| Cookie | js-cookie | 3.0.1 |
|