目录
一、背景描述
二、开发流程
1.引入Mock
2.创建文件
3.需求描述
4.Mock实现
三、总结
一、背景描述
前提:
事情是这样的,老板想要我们写一个demo拿去路演/拉项目,有一些数据,希望前端接一下,写几个表格,画几个图,然后leader们又有其他考量,决定把数据处理完(处理成一群JSON数据)给前端,前端自己写一些查询,分页,绘图,因为数据量不算太大,一个JSON也就最多5MB,所以客户端处理完全OK,于是就这样,前端写所有的一切开始了。
哦,故事的开始是,我使用的是RuoYi的模板,感谢!很规范,让我少了很多繁琐的工作。
二、开发流程
第一步,关于RouYi:若依管理系统
文档:介绍 | RuoYi
第二步,关于Mock:Mock.js
1.引入Mock
因为前端处理所有,所以不是--save dev
npm install mockjs -g
src\main.js
import './mock'; // 执行 mock.js 中的副作用import Mock from 'mockjs'; // 导入 Mock 对象,我们在main中不使用这个,暂时引入来打印数据,等下就删掉console.log(Mock);
试试打印Mock,如果出现这些,代表引入正常了:
2.创建文件
创建如下的结构——data是存放我的一些mock数据,modules是不同模块的mock处理。
src\mock\index.js
import './modules/user' // 引入登录用户模块的 mock export default {}
src\mock\modules\user.js
import Mock from 'mockjs'// 模拟用户登录数据Mock.mock('/login', 'post', (options) => { const { username, password } = JSON.parse(options.body) // 检查用户名和密码 if (username === 'admin' && password === '123456') { return { code: 200, msg: '登录成功', token: '111111' // 模拟一个 token } } else { return { code: 500, msg: '用户不存在/密码错误' } }})// 模拟路由数据Mock.mock('/getRouters', 'get', { code: 200, msg: '操作成功', data: [ { name: 'Project', path: '/project', hidden: false, redirect: 'noRedirect', component: 'Layout', alwaysShow: false, meta: { title: '项目管理', icon: 'form', noCache: false, link: null }, children: [ //... ] }, ]})// 模拟获取用户信息接口Mock.mock('/api/user/info', 'get', { code: 200, message: '获取成功', data: { name: 'admin', roles: ['admin'], avatar: 'https://example.com/avatar.png' }})// 模拟用户列表接口Mock.mock('/api/users', 'get', { code: 200, message: '获取成功', data: Mock.mock({ 'users|10': [ { id: '@id', name: '@cname', age: '@integer(20, 50)', gender: '@pick(["male", "female"])', email: '@email' } ] })})Mock.mock('/logout', 'post', { code: 200, message: '退出登录成功'})export default Mock
上述的操作都是在基于rouyi的Demo定义的返回值,上面写了一些简单的用户登录和获取路由信息的mock,也就相当于平时跟后端接接口的一些过程,只是这部分前端来写了,比较难的是下面部分,前端处理列表数据,并且进行查询等等处理。
3.需求描述
我需要展示一个项目列表,那么项目列表支持,分页和查询功能。
除此之外,我还需要点击列表的某一行,能显示这一个项目里的角色列表,并且也支持分页查询。
首先,我需要的参数和接口如下:
src\api\project.js
import request from '@/utils/request'// 查询项目列表export function listProject(query) { return request({ url: '/project/list', method: 'get', params: query })}// 查询项目内的角色列表export function listData(query) { return request({ url: '/project/role/data/list', method: 'get', params: query })}//query就是下面的queryParams,字段可以根据需求增减const data = reactive({ form: {}, queryParams: { pageNum: 1, pageSize: 10, projectId: undefined, projectStage: undefined, firstStartDate: undefined, endDate: undefined }, rules: { projectName: [{ required: true, message: '项目名称不能为空', trigger: 'blur' }], }})
4.Mock实现
官网上有一个简单的例子:
Mock.mock(/\.json/, function(options) {
return options
})
我这里的数据结构如下:
src\mock\data\projects.json
[ { "id": 1, "projectId": "projectAA", "projectName": "测试项目名称", "totalCases": 174, "firstStartDate": "2022-03-01", "endDate": "", "projectStage": "正在进行中" }]
src\mock\data\project_role.json
{ "projectAA": [ { "id": 1, "projectId": "projectAA", "roleName": "角色名称111", "region": "北区", "province": "天津", "roleProvince": "天津", "roleCity": "天津", "department": "管理组", "roleStatus": "在组", "startDate": "" } ]}
有了数据结构,那么根据官网的例子再扩展一番,就能得到以下:
src\mock\modules\project.js
import Mock from 'mockjs'const baseUrl = 'http://localhost'import projectData from '../data/projects.json'// 项目列表Mock.mock(/\/project\/list/, 'get', (options) => { const url = new URL(options.url, baseUrl) const params = new URLSearchParams(url.search) const pageNum = params.get('pageNum') || 1 const pageSize = params.get('pageSize') || 10 const projectId = (params.get('projectId') || '').toLowerCase() const projectStage = (params.get('projectStage') || '').toLowerCase() const startDateRange = params.get('firstStartDate') || '' const endDateRange = params.get('endDate') || '' const filteredProjects = projectData.filter((project) => { const projectStartDate = new Date(project.firstStartDate) const projectEndDate = new Date(project.endDate) const startDate = new Date(startDateRange) const endDate = new Date(endDateRange) return ( (!projectId || project.projectId.toLowerCase().includes(projectId)) && (!projectPhase || project.projectPhase.toLowerCase().includes(projectPhase)) && (!projectStage || project.projectStage.toLowerCase().includes(projectStage)) && (!startDateRange || projectStartDate >= startDate) && (!endDateRange || projectEndDate <= endDate) ) }) const total = filteredProjects.length const start = (pageNum - 1) * pageSize const end = start + parseInt(pageSize) const pageData = filteredProjects.slice(start, end) return { code: 200, msg: '操作成功', data: { list: pageData, total: total, allList: filteredProjects } }})import projectAndRoleData from '../data/project_role.json'Mock.mock(/\/project\/role\/data\/list/, 'get', (options) => { const url = new URL(options.url, baseUrl) const params = new URLSearchParams(url.search) const projectId = (params.get('projectId') || '').toLowerCase() const pageNum = parseInt(params.get('pageNum')) || 1 const pageSize = parseInt(params.get('pageSize')) || 10 const roleId = (params.get('roleId') || '').toLowerCase() const roleName = (params.get('roleName') || '').toLowerCase() const department = (params.get('department') || '').toLowerCase() // 过滤项目数据 const filteredProjects = Object.keys(projectAndRoleData) .filter((key) => !projectId || key.toLowerCase() === projectId) // 按 projectId 筛选 .map((key) => projectAndRoleData[key]) // 获取 projectId 对应的数据 .flat() // 将结果从嵌套的数组展平 // 进一步过滤数据 const filteredRoles = filteredProjects.filter((role) => { return ( (!roleId || role.roleId.toLowerCase().includes(roleId)) && (!roleName || role.roleName.toLowerCase().includes(roleName)) && (!department || role.department.toLowerCase().includes(department)) ) }) const total = filteredRoles.length const start = (pageNum - 1) * pageSize const end = start + pageSize const pageData = filteredRoles.slice(start, end) return { code: 200, msg: '操作成功', data: { list: pageData, total: total, allList: filteredRoles } }})
以上主要做了这些工作:支持大小写、模糊搜索;支持数字类型的输入;支持日期范围筛选;支持分页
三、总结
上面只是讲了一个简单的例子,关于前端处理列表,其实通过这个,前端可以讲所有的从服务器端获取数据的操作,都通过mock进行拦截,然后自定义返回数据,只是我这里是写一个demo,主要是展示数据,所以对于返回的数据,我并没有做很多处理,只是简单的返回了数据,如果大家有需要,可以自己根据需要,对返回的数据进行处理。