ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

gin-vue-admin 前端工具函数库全解:从 request 到 asyncRouter 的复用规范与源码实践

gin-vue-admin 前端工具函数库全解:从 request 到 asyncRouter 的复用规范与源码实践 后端前端认证鉴权低代码企业应用【免费下载链接】gin-vue-adminViteVue3Gin的开发基础平台支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。项目地址https://gitcode.com/flipped-aurora/gin-vue-admin点击查看免费下载导读本文围绕 gin-vue-admin 前端工程web/src/utils/目录下的统一工具函数层展开系统梳理request.js、dictionary.js、format.js、asyncRouter.js、btnAuth.js等 17 个核心工具模块的职责边界、调用方式与底层实现。读者读完后将掌握在 gin-vue-admin 中优先复用既有能力、杜绝重复造轮子的前端开发规范能够在开发新页面、新接口、新组件时准确选用对应的工具函数并理解动态路由、按钮权限、字典缓存、请求拦截等关键机制的源码级原理。一、核心原则复用优先禁止重复造轮子aiDoc/frontend-backend/frontend-utils.md是 gin-vue-admin 前后端协作边界文档体系中关于前端工具函数复用约束的规范文件同目录下还有 boundary.md 与 frontend-rules.md。它确立了一条贯穿整个前端工程的核心原则开发任何前端功能前必须优先检查并复用src/utils/下已有能力严禁重复造轮子。这一约束的目的很明确gin-vue-admin 的前端基于 Vite Vue3 Element Plus支持 TS/JS 混用将高频横切能力全部收敛到了web/src/utils/目录下包括 HTTP 请求、字典解析、命名转换、系统参数、路由权限、事件通信等。所有工具函数都以统一封装、统一出口的形式存在任何业务页面直接import即可使用从而保证行为一致所有请求都走同一套 token 注入、错误处理、loading 管理逻辑维护集中修复或升级底层能力只需改动一处降低心智负担新成员只需查询工具清单即可找到可复用能力。下文将按功能域逐一剖析这些工具并给出源码实现依据与使用示例。二、HTTP 与数据请求层2.1request.jsHTTP 请求统一入口web/src/utils/request.js是基于 axios 二次封装的全局请求单例是整个前端工程的网络出口。强制使用场景发起 HTTP 请求时必须使用/utils/request。从源码可以看到它在请求拦截器service.interceptors.request中完成了四件核心工作const DEFAULT_REQUEST_TIMEOUT 1000 * 60 * 10 const DEFAULT_LOADING_FORCE_CLOSE_DELAY 30000默认超时未显式传入timeout时默认超时时间为 10 分钟1000 * 60 * 10适用于大文件上传等长耗时场景全局 Loading 管理请求发起后延迟 400ms 显示ElLoading避免瞬时请求闪烁并通过计数器activeAxios支持并发请求合并——只要还有未完成的请求loading 就不关闭同时内置 30 秒强制关闭保护DEFAULT_LOADING_FORCE_CLOSE_DELAY防止异常场景下 loading 永久残留并导出resetLoading用于兜底重置BaseURL 注入config.baseURL config.baseURL || import.meta.env.VITE_BASE_API环境变量VITE_BASE_API定义在web/.env*系列文件中身份信息注入自动携带x-token用户 token与x-user-id用户 ID请求头默认Content-Type: application/json来源为 Pinia 中的 user store。响应拦截器service.interceptors.response的判定逻辑同样值得关注if (response.headers[new-token]) { userStore.setToken(response.headers[new-token]) } if (response.data.code 0 || response.headers.success true) { if (response.headers.msg) { response.data.msg decodeURI(response.headers.msg) } return response.data }Token 续期后端返回new-token响应头时自动更新本地 token实现无感续期统一成功判定code 0或响应头success true视为成功直接返回response.data业务代码拿到的是干净的响应体统一错误提示失败时通过ElMessage弹出后端返回的msg401 统一处理请求返回 401 时通过事件总线emitter.emit(show-error, ...)触发全局错误提示并回调中执行userStore.ClearStorage()与跳转登录页router.push({ name: Login, replace: true })网络异常兜底无响应断网/超时时调用resetLoading()重置所有 loading 状态防止卡死。实践中业务层调用方式为import service from /utils/request // 普通 GET/POST const res await service({ url: /user/info, method: get }) // 不显示全局 loading如轮询、后台静默请求 const res await service({ url: /xxx, method: post, donNotShowLoading: true })2.2 请求工具在业务 API 中的落地业务侧所有 API 定义均统一依赖该封装。以web/src/api/目录下的模块为例它们只负责描述请求什么而 token、loading、错误处理全部交由request.js完成这正是统一入口约束的直接体现。三、字典与数据格式化3.1dictionary.js字典数据获取强制使用场景获取字典数据时必须优先使用/utils/dictionary。web/src/utils/dictionary.js是字典能力的唯一入口向上对接 Pinia 的 dictionary store向下提供两个核心方法。getDict(type, options)支持按深度和指定节点获取字典并内置了缓存 key 生成规则generateCacheKeyexport const getDict async (type, options { depth: 0, value: null }) { // 参数校验type 必须为非空字符串depth 必须为非负数 await dictionaryStore.getDictionary(type, options.depth, options.value) const cacheKey generateCacheKey(type, options.depth, options.value) const result dictionaryStore.dictionaryMap[cacheKey] return Array.isArray(result) ? result : [] }缓存 key 规则为传了value${type}_value_${value}_depth_${depth}未传value且depth 0${type}_tree完整树未传value且depth 0${type}_depth_${depth}指定深度扁平数据。使用示例源码注释中自带// 获取完整的字典树形结构 const dictTree await getDict(user_status) // 获取指定深度的扁平化字典数据 const dictFlat await getDict(user_status, { depth: 2 }) // 获取指定节点的 children const children await getDict(user_status, { value: active })配套的showDictLabel(dict, code, keyCode value, valueCode label)用于将字典 value 翻译成展示 label适合表格列渲染场景// dict 为字典数组code 为待翻译的值 const label showDictLabel(dict, row.status) // 返回对应 label找不到返回 3.2format.js常用格式化能力web/src/utils/format.js集成了布尔值、日期、字典、URL、主题色、UUID 等常用格式化能力是业务页面最常用的工具模块之一主要导出函数能力源码要点formatBoolean(bool)布尔值展示非 null 时输出「是/否」null 输出空串formatDate(time)日期格式化基于date.js的formatTimeToStr输出yyyy-MM-dd hh:mm:ssfilterDict(value, options)字典值翻译递归查找options中value对应的label支持children树形结构filterDataSource(dataSource, value)数据源翻译同 filterDict但额外支持传入数组批量翻译getDictFunc(type)异步字典获取包装getDict(type)ReturnArrImg(arr)图片地址拼接单值/数组统一走getUrl处理兼容数组与非数组入参onDownloadFile(url)文件下载window.open(getUrl(url))setBodyPrimaryColor(color, darkMode)主题色切换计算并注入--el-color-primary及 light/dark 系列 CSS 变量getBaseUrl()BaseURL 获取读取VITE_BASE_API/时返回空串CreateUUID()UUID 生成基于时间戳 performance.now() 随机数符合 UUID v4 格式强制使用场景生成 UUID 时必须优先使用CreateUUID。其实现采用标准 RFC 4122 格式xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx种子由当前时间与performance.now()混合保证同一毫秒内多次调用也能得到不同值export const CreateUUID () { let d new Date().getTime() if (window.performance typeof window.performance.now function) { d performance.now() } return 00000000-0000-0000-0000-000000000000.replace(/0/g, (c) { const r (d Math.random() * 16) % 16 | 0 d Math.floor(d / 16) return (c 0 ? r : (r 0x3) | 0x8).toString(16) }) }主题色能力在个人中心/系统设置中用于动态换肤通过修改 Element Plus 的 CSS 变量实现全局生效。3.3date.js日期格式化web/src/utils/date.js通过扩展Date.prototype.Format提供模板化日期格式化并在文件头注释中给出了完整的占位符约定月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q)可用 12 个占位符年(y)可用 14 个占位符毫秒(S)只能用 1 个占位符13 位数字。示例对照(new Date()).Format(yyyy-MM-dd hh:mm:ss.S) 2006-07-02 08:09:04.423 (new Date()).Format(yyyy-M-d h:m:s.S) 2006-7-2 8:9:4.18对外主要暴露formatTimeToStr(times, pattern)未传pattern时默认yyyy-MM-dd hh:mm:ss。format.js中的formatDate即基于它实现。四、命名转换与字符串工具4.1stringFun.js命名格式转换强制使用场景进行命名格式转换时必须优先使用/utils/stringFun。web/src/utils/stringFun.js提供四个纯函数覆盖前后端字段命名的双向转换// 首字母大写 / 小写 toUpperCase(hello) // Hello toLowerCase(Hello) // hello // 驼峰转下划线ID 特判保持原样 toSQLLine(userName) // user_nameID - ID // 下划线转驼峰 toHump(user_name) // userNametoSQLLine对ID做了特判直接返回原值避免主键字段被误转成_i_d。这类转换在代码生成器、表格列字段映射、前后端字段对齐等场景中高频使用。五、系统参数与全局状态5.1params.js系统参数获取web/src/utils/params.js提供getParams(key)方法统一从 Pinia 的 params store 读取系统参数后端sys_params表配置的全局参数// 同步方式 const res await getParams(key) // 异步函数内使用 const fun async () { res.value await getParams(test) } fun()params store 内部维护paramsMap同一 key 只向后端请求一次后续读取直接命中内存缓存。5.2bus.js跨组件事件通信强制使用场景跨组件通信优先使用事件总线避免滥用 Pinia。web/src/utils/bus.js基于mitt实现了一个极简的全局事件总线import mitt from mitt export const emitter mitt()mitt 是体积极小的事件发射器库提供on/off/emit三个核心方法。request.js的错误上报、closeThisPage.js的关页信号都复用了这个总线。对于一次触发、多处订阅或非层级组件间的通信使用事件总线比把状态硬塞进 Pinia 更轻量、更贴合事件语义。六、路由、标题与权限6.1asyncRouter.js异步路由处理web/src/utils/asyncRouter.js负责将后端返回的路由配置字符串解析为真正的 Vue 组件是动态路由机制的关键一环。它利用 Vite 的import.meta.glob预扫描所有视图组件const viewModules import.meta.glob(../view/**/*.vue) const pluginModules import.meta.glob(../plugin/**/*.vue) export const asyncRouterHandle (asyncRouter) { asyncRouter.forEach((item) { if (item.component typeof item.component string) { item.meta.path /src/ item.component if (item.component.split(/)[0] view) { item.component dynamicImport(viewModules, item.component) } else if (item.component.split(/)[0] plugin) { item.component dynamicImport(pluginModules, item.component) } } if (item.children) { asyncRouterHandle(item.children) } }) }要点路由的component字段在后端以字符串形式存储如view/superAdmin/menu/index前端通过dynamicImport在预扫描的模块表中精确匹配并转换为组件递归处理children支持多级菜单按view/plugin前缀分流插件页面的路由组件同样支持动态加载——这与仓库中web/src/plugin/目录下的插件页面机制一一对应。6.2btnAuth.js按钮级权限控制强制使用场景处理按钮权限时必须优先使用useBtnAuth。web/src/utils/btnAuth.js提供组合式函数useBtnAuthexport const useBtnAuth () { const route useRoute() return route.meta.btns || reactive({}) }它直接读取当前路由meta.btns由后端按用户角色下发的按钮权限集返回一个响应式对象。页面中典型用法const btns useBtnAuth() // 模板中v-ifbtns[user:add] 控制新增按钮显隐配合仓库中的按钮权限指令web/src/directive/auth.js与权限源数据server/source/system/authority.go等构成路由级 按钮级的完整 RBAC 前端实现。6.3fmtRouterTitle.js与page.js页面标题生成web/src/utils/fmtRouterTitle.js的fmtTitle(title, now)支持在标题中使用${param}占位符运行时从路由的params/query中取值替换export const fmtTitle (title, now) { const reg /\$\{(.?)\}/ // 逐个替换 ${key} 为 now.params[key] || now.query[key] }web/src/utils/page.js的getPageTitle(pageTitle, route)在其基础上拼接应用名最终生成浏览器标签页标题export default function getPageTitle(pageTitle, route) { if (pageTitle) { const title fmtTitle(pageTitle, route) return ${title} - ${config.appName} } return ${config.appName} }应用名来自web/src/core/config.js中的config.appName。例如路由配置标题为用户详情 - ${id}跳转后标签页会显示为「用户详情 - 1024 - xxx」。6.4closeThisPage.js关闭当前标签页web/src/utils/closeThisPage.js通过事件总线广播关闭信号import { emitter } from /utils/bus.js export const closeThisPage () { emitter.emit(closeThisPage) }标签页管理器web/src/view/layout/tabs/订阅该事件后执行关闭当前 tab 并跳转的逻辑。业务页面如详情页、表单页在保存完成后调用closeThisPage()即可优雅返回无需感知内部实现。七、资源、媒体与 DOM 工具7.1image.js图片压缩与 URL 处理web/src/utils/image.js默认导出ImageCompress类用于上传前的图片压缩class ImageCompress { constructor(file, fileSize, maxWH 1920) // 文件、目标大小KB、最大边长 compress() // 压缩主流程返回 PromiseFile }实现原理FileReader读取文件为 DataURL → 绘制到 canvas → 等比缩放dWH保持长宽比长边不超过maxWH默认 1920→canvas.toDataURL(fileType, 0.9)以 0.9 质量导出 → 经dataURLtoBlob转回 Blob 并包装为File返回。若压缩后体积仍超过fileSize目标值会在控制台输出告警。同文件还导出getUrl(url)拼接文件访问地址基于VITE_FILE_API环境变量非http开头的相对路径自动补全根路径/时直接返回原值isVideoExt(url)/isVideoMime(type)/isImageMime(type)按扩展名.mp4、.mov、.webm、.ogg或 MIME 类型jpeg/png/webp/svg 等判断媒体类型供列表展示、上传校验复用。7.2downloadImg.js图片下载web/src/utils/downloadImg.js的downloadImage(imgsrc, name)采用跨域 canvas 重绘方案规避直接下载的跨域限制image.setAttribute(crossOrigin, anonymous) // 图片加载完成后绘制到 canvastoDataURL(image/png) 转 base64 // 创建 a downloadname 并派发 click 事件触发下载name缺省时默认文件名为photo。7.3event.jsDOM 事件管理web/src/utils/event.js提供addEventListen与removeEventListen两个薄封装内部先做能力检测target.addEventListener存在且为函数再绑定/解绑并透传capture捕获参数。用于统一事件绑定入口避免重复书写能力判断逻辑。7.4env.js环境判断web/src/utils/env.js直接暴露 Vite 注入的环境标志export const isDev import.meta.env.DEV export const isProd import.meta.env.PROD业务中可据此在开发/生产环境执行差异化逻辑如本地调试打印、生产环境埋点。7.5doc.js文档跳转web/src/utils/doc.js的toDoc(url)以新窗口打开文档链接export const toDoc (url) { window.open(url, _blank) }通常用于帮助文档使用指南等入口保持当前页面状态不被覆盖。八、强制使用场景对照速查原文档明确了以下强制性场景任何新代码都不得绕过场景必须使用的工具对应源码发起 HTTP 请求/utils/requestweb/src/utils/request.js获取字典数据/utils/dictionarygetDictweb/src/utils/dictionary.js生成 UUIDCreateUUID来自 format.jsweb/src/utils/format.js处理按钮权限useBtnAuthweb/src/utils/btnAuth.js命名格式转换/utils/stringFunweb/src/utils/stringFun.js跨组件通信事件总线emitterbus.js避免滥用 Piniaweb/src/utils/bus.js九、开发前的复用检查清单结合 frontend-utils.md 的规范与上述源码分析建议在开发每个前端功能前依次自检要发请求确认是否已在web/src/api/下有过同类接口定义并一律经由/utils/request发出不要新建 axios 实例要渲染字典/下拉/表格枚举先查getDict/filterDict/showDictLabel/filterDataSource是否已覆盖不要手写 value→label 映射要拼接图片/文件地址使用getUrl不要硬编码VITE_FILE_API要做命名转换使用toSQLLine/toHump不要自行编写正则要控制按钮显隐使用useBtnAuth不要重复从接口拉取权限要做组件间通知优先emitter事件总线只有需要跨页面共享响应式状态时才使用 Pinia要动态路由/标题/关页分别对应asyncRouterHandle、getPageTitle、closeThisPage这些能力在布局与路由基建中已闭环业务侧只需调用。遵循这份清单即可让新功能无缝融入 gin-vue-admin 现有的请求、权限、字典与路由体系既降低维护成本也保证整个工程行为的一致性。赞分享后端前端认证鉴权低代码企业应用【免费下载链接】gin-vue-adminViteVue3Gin的开发基础平台支持TS和JS混用。它集成了JWT鉴权、权限管理、动态路由、显隐可控组件、分页封装、多点登录拦截、资源权限、上传下载、代码生成器【可AI辅助】、表单生成器和可配置的导入导出等开发必备功能。项目地址https://gitcode.com/flipped-aurora/gin-vue-admin点击查看免费下载相关推荐OpenCore Legacy Patcher终极指南让老Mac免费运行最新macOS的完整教程OpenCore Legacy Patcher终极指南让老Mac免费运行最新macOS的完整教程 你是否有一台被苹果官方抛弃的老款Mac当系统更新提示后端前端认证鉴权低代码企业应用gin-vue-admin 前端代码示例指南API 封装、Pinia Store、页面组件与工具函数复用规范gin vue admin 前端代码示例指南API 封装、Pinia Store、页面组件与工具函数复用规范 本篇指南以 gin vue admin 仓库 a后端前端认证鉴权低代码任务调度gin-vue-admin 前端工具函数复用指南以 src/utils 为核心的能力沉淀与调用规范gin vue admin 前端工具函数复用指南以 src/utils 为核心的能力沉淀与调用规范 导读 本指南围绕 gin vue admin 前端工程中后端前端认证鉴权低代码任务调度上一篇Flow.Launcher插件依赖自动安装智能解决扩展运行环境的完整指南下一篇Tiptap 核心包 tiptap/core 演进全解析从 v3 重构到 Decorations 时代创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表