Vue2 使用 vue-cli-plugin-mock 本地模拟数据
安装
npm i -D vue-cli-plugin-mock
@/mock
写一个入口文件 ./mock/index.js
mock示例写法一
const mockMap = {
'GET /api/user': {
// obj
id: 1,
username: 'kenny',
sex: 6,
},
'GET /api/user/list': [
// array
{
id: 1,
username: 'kenny',
sex: 6,
},
{
id: 2,
username: 'kenny',
sex: 6,
},
],
'POST /api/login/account': (req, res) => {
// express router style
const { password, username } = req.body;
if (password === '888888' && username === 'admin') {
return res.json({
status: 'ok',
code: 0,
token: 'sdfsdfsdfdsf',
data: {
id: 1,
username: 'kenny',
sex: 6,
},
});
} else {
return res.json({
status: 'error',
code: 403,
});
}
},
'DELETE /api/user/:id': (req, res) => {
console.log('---->', req.body);
console.log('---->', req.params.id); // request params
res.send({ status: 'ok', message: 'delete success!' });
},
};
module.exports = mockMap;
示例写法二
module.exports = [
{
path: '/api/user',
handler: (req, res) => {
return res.json({ username: 'admin', sex: 5 });
},
},
{
path: '/api/list',
handler: function (req, res) {
let query = req.query || {};
return res.json({
limit: query.limit,
offset: query.offset,
list: [
{ username: 'admin1', sex: 1 },
{ username: 'admin2', sex: 0 },
],
});
},
},
{
path: '/repos/hello',
handler: (req, res) => {
return res.json({ text: 'this is from mock server' });
},
},
{
path: '/api/userinfo/:id',
handler: (req, res) => {
return res.json({
id: req.params.id,
username: 'kenny',
});
},
},
{
path: '/api/user/list/:id/:type',
handler: (req, res) => {
return res.json({
id: req.params.id,
type: req.params.type,
});
},
},
{
path: '/api/login/account',
method: 'post',
handler: (req, res) => {
const { password, username } = req.body;
if (password === '888888' && username === 'admin') {
return res.json({
status: 'ok',
code: 0,
token: 'sdfsdfsdfdsf',
data: {
id: 1,
username: 'kenny',
sex: 6,
},
});
} else {
return res.json({ status: 'error', code: 403 });
}
},
},
{
method: 'delete',
path: '/api/user/:id',
handler: (req, res) => {
res.send({ status: 'ok', message: '删除成功!' });
},
},
];
在vue.config.js中添加
module.exports = {
pluginOptions: {
mock: { entry: './test/mock.js', debug: true },
},
};
test mock with curl
➜ ~ curl -X GET http://127.0.0.1:4000/api/user
{"id":1,"username":"kenny","sex":6}
➜ ~ curl -X GET http://127.0.0.1:4000/api/user/list
[{"id":1,"username":"kenny","sex":6},{"id":2,"username":"kenny","sex":6}]
➜ ~ curl -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"username":"admin","password":"888888"}' http://127.0.0.1:4000/api/login/account
{"status":"ok","code":0,"token":"sdfsdfsdfdsf","data":{"id":1,"username":"kenny","sex":6}}
➜ ~ curl -X DELETE http://127.0.0.1:4000/api/user/88
{"status":"ok","message":"delete success!"}
项目实战
package.json中添加
"vue-cli-plugin-mock": "^1.0.2",
@/mock
方案一
自动注册
// src\mock\index.js
const Mock = require('mockjs')
export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}
function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
// https://expressjs.com/en/4x/api.html#req
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
const mocksContext = require.context('./modules/', true, /.js$/)
mocksContext.keys().forEach(file_name => {
// 获取文件中的 default 模块
const mocks = mocksContext(file_name)
for (const mock of mocks) {
Mock.mock(
new RegExp(`${process.env.VUE_APP_API_ROOT}mock/${mock.url}`),
mock.type || 'get',
XHR2ExpressReqWrap(mock.result)
)
}
})
mock数据
// src\mock\modules\login.js
module.exports = [
{
url: '/v1/user/login',
type: 'post',
result: option => {
return {
msg: '',
code: '0',
data: {
userName: option.body.userName,
token: 'eyJhbGciOiJIUzUxMiJ9EwLW48EL5ijVqcjFFuN9n3V2K3N-jU5L-_zjnLLHTQpfTY9Tjg',
failure_time: Date.parse(new Date()) / 1000 + 24 * 60 * 60
}
};
}
},
{
url: '/v1/user/query',
type: 'get',
result: option => {
let userList = [];
if (option.query.isSelf === 0) {
const user = {
id: 650000201109297300,
userName: 'Donna Miller',
cnName: '韩明',
email: 'r.codqydjldp@jjxn.td',
phone: 'sunt ut enim et cupidatat',
userLevel: 2,
deptId: 5551652833778924,
createdAt: '2004-08-31 00:07:01',
updatedAt: '2022-07-20 04:12:28',
deptPathName: 'dolore',
deptName: '研究院',
parentId: 3637678309766032,
userId: 370000199909037950,
hasChildren: 90371184.32199448,
deptPathId: '4061621791721624'
};
userList.push(user);
}
return {
msg: '查询成功',
code: '0',
data: userList
};
}
},
{
url: 'member/permission',
type: 'get',
result: option => {
let permissions = [];
if (option.query.account == 'admin') {
permissions = [
'permission.browse',
'permission.create',
'permission.edit',
'permission.remove'
];
} else if (option.query.account == 'test') {
permissions = ['permission.browse'];
}
return {
msg: '',
code: '0',
data: {
permissions
}
};
}
}
];
module.exports = [
{
url: '/v1/user/update',
type: 'post',
result: option => {
return {
msg: '修改成功',
code: '0',
data: {}
};
}
},
{
url: '/v1/user/create',
type: 'post',
result: option => {
return {
msg: '新增成功',
code: '0',
data: {}
};
}
},
{
url: '/v1/user/delete',
type: 'post',
result: option => {
return {
msg: '删除成功',
code: '0',
data: {}
};
}
}
];
main.js中引入
import './mock'
方案二
自动注册
// src\mock\server.js
let mockMap = {}
const mocksContext = require.context('./server-modules/', false, /.js$/)
mocksContext.keys().forEach(file_name => {
mockMap = Object.assign(mockMap, mocksContext(file_name).default)
})
export default mockMap
mock数据
// src\mock\server-modules\login.js
const Mock = require('mockjs');
export default {
'POST /mock/v1/user/login': (req, res) => {
return res.json(
Mock.mock({
msg: '',
code: '0',
data: {
userName: req.body.userName,
token: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
failure_time: Date.parse(new Date()) / 1000 + 24 * 60 * 60
}
})
);
},
'GET /mock/member/permission': (req, res) => {
let permissions = [];
if (req.query.account == 'admin') {
permissions = [
'permission.browse',
'permission.create',
'permission.edit',
'permission.remove'
];
} else if (req.query.account == 'test') {
permissions = ['permission.browse'];
}
return res.json({
error: '',
status: 1,
data: {
permissions
}
});
}
};
// src\mock\server-modules\user.js
const Mock = require('mockjs');
Mock.Random.extend({
phone: function () {
var phonePrefixs = ['132', '135', '189'];
return this.pick(phonePrefixs) + Mock.mock(/\d{8}/);
}
});
export default {
'POST /mock/v1/user/update': (req, res) => {
return res.json(
Mock.mock({
msg: '修改成功',
code: '0',
data: {
userName: req.body.userName,
token: '@string',
failure_time: Date.parse(new Date()) / 1000 + 24 * 60 * 60
}
})
);
},
'POST /mock/v1/user/create': (req, res) => {
return res.json(
Mock.mock({
msg: '新增成功',
code: '0',
data: {
userName: req.body.userName,
token: '@string',
failure_time: Date.parse(new Date()) / 1000 + 24 * 60 * 60
}
})
);
},
'POST /mock/v1/user/delete': (req, res) => {
return res.json(
Mock.mock({
msg: '删除成功',
code: '0',
data: {}
})
);
},
'GET /mock/v1/user/query': (req, res) => {
const list = [];
if (req.query.isSelf == 1) {
const currentUser = admin;
list.push(currentUser);
} else {
for (let i = 0; i < 10; i++) {
let user = {
id: Mock.mock('@increment'),
userName: Mock.Random.cname(),
cnName: Mock.Random.cname(),
email: Mock.Random.email('163.com'),
phone: Mock.Random.phone(),
userLevel: Mock.Random.integer(1, 2),
deptId: Mock.Random.integer(1, 5),
createdAt: Mock.Random.date('yyyy-MM-dd HH:mm:ss'),
updatedAt: Mock.Random.date('yyyy-MM-dd HH:mm:ss'),
deptPathName: Mock.Random.city(),
deptName: Mock.Random.cname(),
parentId: Mock.Random.integer(1, 10),
userId: Mock.mock('@increment'),
hasChildren: Mock.Random.integer(0, 1)
};
list.push(user);
}
}
return res.json(
Mock.mock({
msg: '',
code: '0',
data: list
})
);
}
};
const admin = {
id: 3, //当前对象唯一id,用于前端构造树结构
userName: 'admin', //为空,代表该组暂无组长
cnName: '管理员',
email: 'admin@163.com',
phone: '15381086786',
userLevel: 0,
deptId: 1, //当前部门的id
createdAt: '2022-04-19T08:00:22.684Z',
updatedAt: '2022-04-22T05:50:47.708Z',
deptPathName: '/根部门',
deptName: '根部门',
parentId: 2, //当前对象的父节点id,用于前端构造树结构
userId: 3, //为null代表该组暂无组长
hasChildren: 0
};
const leader = {
id: 2, //当前对象唯一id,用于前端构造树结构
userName: 'longmo', //为空,代表该组暂无组长
cnName: '龙陌',
email: 'longmo@163.com',
phone: '15381086786',
userLevel: 1,
deptId: 1, //当前部门的id
createdAt: '2022-04-19T08:00:22.684Z',
updatedAt: '2022-04-22T05:50:47.708Z',
deptPathName: '/根部门/测试/web前端组',
deptName: 'web前端组',
parentId: 2, //当前对象的父节点id,用于前端构造树结构
userId: 2, //为null代表该组暂无组长
hasChildren: 0
};
const member = {
id: 3, //当前对象唯一id,用于前端构造树结构
userName: 'zhangsan', //为空,代表该组暂无组长
cnName: '张三',
email: 'zhangsan@163.com',
phone: '15381086786',
userLevel: 2,
deptId: 1, //当前部门的id
createdAt: '2022-04-19T08:00:22.684Z',
updatedAt: '2022-04-22T05:50:47.708Z',
deptPathName: '/根部门/测试/web前端组',
deptName: 'web前端组',
parentId: 2, //当前对象的父节点id,用于前端构造树结构
userId: 3, //为null代表该组暂无组长
hasChildren: 0
};
vue.config.js中添加
pluginOptions: {
mock: {
entry: './src/mock/server.js',
debug: true,
disable: true
}
},