目录
一、背景描述
前提:
事情是这样的,老板想要我们写一个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
javascript
import './modules/user' // 引入登录用户模块的 mock
export default {}
src\mock\modules\user.js
javascript
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
javascript
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
javascript
[
{
"id": 1,
"projectId": "projectAA",
"projectName": "测试项目名称",
"totalCases": 174,
"firstStartDate": "2022-03-01",
"endDate": "",
"projectStage": "正在进行中"
}
]
src\mock\data\project_role.json
javascript
{
"projectAA": [
{
"id": 1,
"projectId": "projectAA",
"roleName": "角色名称111",
"region": "北区",
"province": "天津",
"roleProvince": "天津",
"roleCity": "天津",
"department": "管理组",
"roleStatus": "在组",
"startDate": ""
}
]
}
有了数据结构,那么根据官网的例子再扩展一番,就能得到以下:
src\mock\modules\project.js
javascript
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,主要是展示数据,所以对于返回的数据,我并没有做很多处理,只是简单的返回了数据,如果大家有需要,可以自己根据需要,对返回的数据进行处理。