当前位置: 首页 > news >正文

Vue3+TS+Vite项目实战:5分钟搞定Mock数据接入(附完整代码)

Vue3+TS+Vite项目实战:5分钟实现动态权限Mock系统

最近在重构后台管理系统时,遇到一个典型痛点:前端页面都开发完了,后端接口还在设计中。这种前后端进度不匹配的情况,相信每个前端开发者都深有体会。今天分享的这套Mock方案,不仅能模拟基础数据返回,还能完整复现动态路由权限控制的业务场景,真正实现"前后端分离开发"的理想状态。

1. 环境搭建与基础配置

首先确保项目已经初始化了Vue3+TypeScript+Vite环境。如果还没创建项目,可以通过以下命令快速初始化:

npm create vite@latest my-vue-app --template vue-ts

进入项目目录后,安装Mock方案的核心依赖:

npm install vite-plugin-mock mockjs -D

这里我们选择vite-plugin-mock而不是常见的mockjs单独使用,是因为它与Vite深度集成,支持热更新且配置更简单。同时安装mockjs作为数据生成工具。

在项目根目录创建mock文件夹,这是存放所有Mock数据的约定目录。新建mock/user.ts文件,开始编写我们的第一个Mock接口:

// mock/user.ts import { MockMethod } from 'vite-plugin-mock' export default [ { url: '/api/login', method: 'post', timeout: 500, response: () => { return { code: 200, data: { token: 'mock-token-123456', username: 'admin' } } } } ] as MockMethod[]

注意这里使用了TypeScript的类型断言,确保我们的Mock配置符合vite-plugin-mock的类型要求。

2. Vite配置与Mock服务启用

接下来配置vite.config.ts文件,启用Mock服务:

// vite.config.ts import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import { viteMockServe } from 'vite-plugin-mock' export default defineConfig({ plugins: [ vue(), viteMockServe({ mockPath: 'mock', // Mock文件存放目录 localEnabled: true, // 开发环境启用 prodEnabled: false, // 生产环境禁用 injectCode: ` import { setupProdMockServer } from '../mock'; setupProdMockServer(); ` // 可选的生产环境Mock方案 }) ] })

关键配置参数说明:

参数名类型默认值说明
mockPathstring'mock'Mock文件存放目录
localEnabledbooleanfalse开发环境是否启用
prodEnabledbooleanfalse生产环境是否启用
loggerbooleantrue是否在控制台显示请求日志
injectCodestring''注入到main.ts的代码

配置完成后,启动开发服务器,Mock服务会自动生效:

npm run dev

3. 实现动态路由权限Mock

现在我们来模拟一个完整的动态路由权限控制系统。首先在mock/user.ts中扩展路由数据:

// mock/user.ts const dynamicRoutes = [ { path: '/system', component: 'Layout', meta: { title: '系统管理', icon: 'setting', roles: ['admin'] }, children: [ { path: 'user', component: 'system/user', meta: { title: '用户管理', roles: ['admin'] } } ] }, { path: '/dashboard', component: 'Layout', meta: { title: '仪表盘', icon: 'dashboard', roles: ['admin', 'editor'] } } ] export default [ // 登录接口 { url: '/api/login', method: 'post', response: ({ body }) => { if (body.username === 'admin') { return { code: 200, data: { token: 'admin-token', roles: ['admin'] } } } else { return { code: 200, data: { token: 'editor-token', roles: ['editor'] } } } } }, // 路由接口 { url: '/api/routes', method: 'get', response: ({ headers }) => { const token = headers.authorization if (!token) { return { code: 401, message: '未授权' } } const isAdmin = token.includes('admin') return { code: 200, data: dynamicRoutes.filter(route => isAdmin || !route.meta?.roles || route.meta.roles.includes('editor') ) } } } ] as MockMethod[]

这个Mock实现了几项关键功能:

  1. 根据不同用户返回不同token
  2. 基于token中的角色信息过滤路由
  3. 完整的权限控制逻辑

4. 前端业务代码集成

在前端项目中,我们需要创建对应的请求和状态管理。首先封装axios实例:

// src/utils/request.ts import axios from 'axios' const service = axios.create({ baseURL: import.meta.env.VITE_API_URL, timeout: 5000 }) // 请求拦截器 service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers.Authorization = `Bearer ${token}` } return config }) // 响应拦截器 service.interceptors.response.use( response => { return response.data }, error => { return Promise.reject(error) } ) export default service

然后实现登录和路由获取的逻辑:

// src/api/user.ts import request from '@/utils/request' interface LoginData { username: string password: string } interface RouteItem { path: string component: string meta?: { title?: string icon?: string roles?: string[] } } export const login = (data: LoginData) => { return request({ url: '/api/login', method: 'post', data }) } export const getRoutes = () => { return request<RouteItem[]>({ url: '/api/routes', method: 'get' }) }

在Pinia/Vuex中管理用户状态和路由:

// src/store/user.ts import { defineStore } from 'pinia' import { login, getRoutes } from '@/api/user' export const useUserStore = defineStore('user', { state: () => ({ token: '', routes: [] as RouteItem[], roles: [] as string[] }), actions: { async login(loginData: LoginData) { const res = await login(loginData) this.token = res.data.token this.roles = res.data.roles localStorage.setItem('token', res.data.token) }, async fetchRoutes() { const res = await getRoutes() this.routes = res.data return res.data } } })

5. 常见问题与调试技巧

在实际开发中,可能会遇到以下典型问题:

问题1:Mock接口不生效

  • 检查vite.config.ts中的localEnabled是否设置为true
  • 确认Mock文件后缀为.ts且位于正确目录
  • 查看控制台是否有Mock服务启动日志

问题2:生产环境意外启用Mock

  • 确保prodEnabled设置为false
  • 可以通过环境变量动态控制:
    viteMockServe({ localEnabled: import.meta.env.DEV, prodEnabled: false })

问题3:TypeScript类型报错

  • 安装@types/mockjs获取类型定义
  • 为自定义Mock数据添加类型注解:
    interface MockResponse { code: number data: any message?: string } const response: MockResponse = { code: 200, data: { /*...*/ } }

调试时可以使用浏览器开发者工具的Network面板查看Mock请求,所有Mock请求都会带有[vite-plugin-mock]前缀的标记。

6. 高级Mock技巧

对于更复杂的场景,我们可以实现以下高级功能:

动态响应数据

{ url: '/api/user/:id', method: 'get', response: ({ query }) => { return { code: 200, data: { id: query.id, name: `用户${query.id}`, age: Math.floor(Math.random() * 30) + 20 } } } }

延迟响应模拟网络状况

{ url: '/api/slow', method: 'get', timeout: 2000, // 2秒延迟 response: () => ({ /*...*/ }) }

Mock文件分模块管理

/mock /system user.ts role.ts /dashboard analysis.ts index.ts // 统一导出

index.ts中聚合所有Mock模块:

import system from './system/user' import dashboard from './dashboard/analysis' export default [...system, ...dashboard]

使用Mock.js生成更真实的数据

import Mock from 'mockjs' { url: '/api/users', method: 'get', response: () => { return Mock.mock({ 'list|10': [{ 'id|+1': 1, 'name': '@cname', 'age|20-40': 1, 'email': '@email', 'address': '@county(true)' }] }) } }

这套Mock方案已经在我们多个线上项目中得到验证,特别是在大型后台管理系统开发中,能够显著提升前后端并行开发效率。实际使用中可以根据项目需求,灵活调整Mock数据的复杂度和响应逻辑。

http://www.jsqmd.com/news/577472/

相关文章:

  • 实战指南:用快马平台生成基于openclaw的mac数据清洗工具
  • 基于Python的个性化电影推荐系统毕业设计
  • Your build is currently configured to use incompatible Java 26 and Gradle 8.13. Cannot sync the proj
  • 破局双系统文件壁垒:WinBtrfs驱动终极应用指南
  • 2026年 江苏厂房装修设计公司推荐榜:专业工厂/办公楼/写字楼装修,打造高效办公与生产空间 - 品牌企业推荐师(官方)
  • 新手福音:在快马平台交互式学习openclaw更新命令语法与参数
  • 请描述在 Linux 系统中如何进行磁盘配额管理。
  • BROADCHIP广芯 BCT2020EUK33-TR SOT23-5 线性稳压器(LDO)
  • 告别内置数据库:NocoBase企业级部署为何推荐外接MySQL?实战配置详解
  • 别再只盯着漏洞了!通过一次钓鱼邮件演练,带你掌握恶意流量的5个关键特征
  • 基于Python的企业内部小型网络管理系统毕业设计源码
  • 从理论到实践:手把手教你用MATLAB构建LSSVR代理模型
  • 2026短视频下载工具优质推荐榜:短视频批量下载神器/能去水印的app推荐/自媒体去水印工具/选择指南 - 优质品牌商家
  • 如何在 Linux 系统中查看和管理网络接口?
  • SEO 关键词优化对于电商网站有哪些具体应用_SEO 关键词优化与广告投放之间的联系是什么
  • 战略·组织·人才·文化:企业发展的四维密码
  • 比话降AI和嘎嘎降AI哪个好知网用户怎么选
  • CLAP模型ONNX转换教程:跨平台部署方案
  • 110. Rancher Prime 注册升级因 SCC 注册命名空间所有权冲突而失败
  • Vue2项目实战:v-md-editor从安装到二次封装全流程(附常见问题解决)
  • CF1205C Palindromic Paths
  • 3分钟终极指南:如何用Fast-GitHub插件彻底解决GitHub访问缓慢问题
  • 从星链到遥感卫星:工程师视角下的轨道摄动实战避坑指南
  • 破坏性测试实战指南:从理论到实践的完整流程解析
  • SEO_2024年最新SEO实战策略,助你获取精准流量
  • 破解专精特新小巨人申报难题:DPMR四阶申报法如何提升通过率? - 速递信息
  • 五加同创:钢制平开门/防弹门窗/防爆墙/防爆窗/防爆门/防辐射门/随道防护门/隔声门/隔音门/医疗门/密闭窗/密闭门/选择指南 - 优质品牌商家
  • 111. Azure AD 客户端秘密到期导致 Rancher 登录失败
  • GitHub中文界面插件实战:深度解析智能翻译引擎与进阶定制方案
  • ESP32-S3 驱动 OV2640 摄像头:从嘉立创例程到AP模式无线图传