MirageJS 使用总结 vue2上亲测使用
注:MirageJS 英文文档看的头疼,且百度上都是片段比较多,本着拿来主义的思路,就把代码粘贴上,这样不仅方便自己,也能方便大家
简单介绍一下他的好处及功能
MirageJS 是一个用于模拟服务器端数据和网络请求的 JavaScript 库,它可以帮助开发者在前端环境中创建假数据、定义路由和处理请求。
主要功能:
-
模拟数据:MirageJS 允许你在前端环境中创建模拟的数据库,并使用模型来定义数据结构。你可以使用 MirageJS 提供的模型和关联关系来创建和管理数据。
-
路由处理:你可以使用 MirageJS 定义 API 路由,指定不同的 HTTP 方法和 URL,以及对应的处理函数。这样,在前端进行开发时,你可以模拟后端 API 的行为,并根据需要返回模拟的数据。
-
数据序列化和反序列化:MirageJS 提供了序列化器(Serializer)来控制数据的序列化和反序列化过程。你可以定义不同的序列化器来适应不同的数据格式和需求。
-
响应延迟和错误模拟:MirageJS 允许你模拟网络请求的延迟和错误,以便测试和调试前端应用的响应能力和容错性。
-
拦截 AJAX 请求:MirageJS 可以拦截通过 Fetch API 或 Axios 等方式发送的 AJAX 请求,并将其重定向到 MirageJS 定义的路由处理函数中。
-
数据过滤和排序:MirageJS 支持对模拟数据进行过滤和排序,以便在开发过程中模拟真实的后端数据查询。
-
认证和授权:MirageJS 提供了一些辅助函数和方法,用于模拟用户认证和授权过程,并模拟受限资源的访问权限。
安装命令
# 使用 npm 安装 npm install --save-dev miragejs # 使用 Yarn 安装 yarn add --dev miragejs
新建一个mirage.js的文件夹,目前我觉得能日常用的代码都在这
import { createServer, Model, Factory } from 'miragejs' export default function makeServer () { return createServer({ models: { user: Model }, // seeds (server) { // server.create('user', { name: 'Alice' }) // server.create('user', { name: 'Bob' }) // }, // 生成模拟数据 factories: { user: Factory.extend({ name (i) { return `设备 ${String.fromCharCode(65 + i)}` }, title (i) { return `Title ${i}` }, value () { return Math.floor(Math.random() * 100) }, time () { const date = new Date() const formattedDate = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}` return formattedDate } }) }, seeds (server) { server.createList('user', 20) }, routes () { // this.namespace = '/cs' 因为我不是全局引入,所以这个我就直接写进接口里了,不然我自测的时候发现,当前页的接口会被拦截 // 列表,带分页,带参数 this.get('/cs/devicesList', (schema, request) => { const page = parseInt(request.queryParams.page) || 1 const pageSize = request.queryParams.pageSize || 5 let users = schema.users.all() // 筛选逻辑 // const filter = request.queryParams.filter // if (filter) { // users = users.filter(user => user.name.includes(filter)) // } // 根据多个条件进行筛选 if (request.queryParams.name) { users = users.filter(user => user.name === request.queryParams.name) } if (request.queryParams.valueMin) { users = users.filter(user => user.value >= request.queryParams.valueMin) } if (request.queryParams.valueMax) { users = users.filter(user => user.value <= request.queryParams.valueMax) } const totalPages = Math.ceil(users.length / pageSize) const start = (page - 1) * pageSize const end = start + pageSize const data = users.slice(start, end) return { data: data, meta: { page: page, pageSize: pageSize, totalPages: totalPages } } }) // 设备汇总 this.get('/cs/summary', (schema) => { let users = schema.users.all() return { total: users.length, // 总数 Certified: Math.ceil(users.length * 0.3), // 已认证 onLine: Math.ceil(users.length * 0.3) + 1, // 在线 offline: users.length - (Math.ceil(users.length * 0.3) + 1) - 10, logOff: 10 } }) // 设备(单纯)列表 this.get('/cs/devices', (schema) => { return schema.users.all() }) // 获取特定用户 this.get('/cs/obtain/:id', (schema, request) => { let id = request.params.id return schema.users.find(id) }) // 创建用户 this.post('/cs/add', (schema, request) => { let attrs = JSON.parse(request.requestBody) return schema.users.create(attrs) }) // 更新用户 this.put('/cs/renew/:id', (schema, request) => { let id = request.params.id let attrs = JSON.parse(request.requestBody) let user = schema.users.find(id) return user.update(attrs) }) // 删除用户 this.delete('/cs/delete/:id', (schema, request) => { let id = request.params.id schema.users.find(id).destroy() return schema.users.all() // 返回删除后的用户列表 }) // 批量删除用户 this.delete('/cs/delete', (schema, request) => { const ids = JSON.parse(request.requestBody).ids ids.forEach((id) => { schema.users.find(id).destroy() }) return schema.users.all() }) // 其他需要模拟的接口 // 当需要跳过的请求时,使用 this.passthrough() 我是局部使用,且和api接口共存,所以需要加上防止路由拦截把所有接口都搞挂了咯 this.passthrough('/system/**') } }) }
引入文件/使用
// axios.get('/cs/devices').then(response => { // console.log('===111=') // console.log('=====/cs/users=', JSON.stringify(response.data.users)) // }) // .catch(error => { // console.log('Error fetching users:', error) // }) // axios.get('/cs/devicesList', { params: { page: 1, pageSize: 2 } }) // .then(response => { // // const users = response.data.data // // const meta = response.data.meta // // 处理分页数据和元数据 // console.log('=====/cs/usersPaging=', JSON.stringify(response.data.data)) // console.log('=====/cs/usersPaging=', JSON.stringify(response.data.meta)) // }) // .catch(error => { // console.log(error) // }) // axios.get('/cs/summary').then(response => { // console.log('=====/cs/summary=', JSON.stringify(response.data)) // }) // .catch(error => { // console.log(error) // }) // axios.delete('/cs/delete/1', { // method: 'DELETE' // }).then(response => { // console.log('=====/cs/delete=', JSON.stringify(response)) // }) // .catch(error => { // console.log('=====/cs/delete==---=', error) // }) // axios.get('/cs/obtain/1').then(response => { // console.log('=====/cs/obtain=', JSON.stringify(response.data)) // }) // .catch(error => { // console.log(error) // }) // axios.post('/cs/add', { // data: [{ // 'time': '2024-03-14 20:13', // 'value': 10086, // 'title': 'Title 10086', // 'name': '设备 10086' // }] // }).then(response => { // console.log('===111=') // console.log('=====/cs/users=', JSON.stringify(response.data.users)) // }) // .catch(error => { // console.log('Error fetching users:', error) // }) axios.delete('/cs/delete', { data: { ids: ['1', '3', '5', '7', '9'] } }).then(response => { console.log('=====/cs/delete=', JSON.stringify(response)) }) .catch(error => { console.log('=====/cs/delete==---=', error) }) axios.get('/cs/devices').then(response => { console.log('===111=') console.log('===2==/cs/devices=', JSON.stringify(response.data.users)) }) .catch(error => { console.log('Error fetching users:', error) })
场景:n级树
MirageJS 中处理具有多级关系的树形数据,并包含关系ID、父级ID和层级ID
新增可以不限制层级
删除,父级中若是有子层级内容的,则无法删除
默认数据中最少有两到三个层级数据
(这个我没测,有兴趣的可以试试)
import { createServer, Model, RestSerializer, Response } from 'miragejs'; import axios from 'axios'; // 创建 MirageJS 服务器 export function makeServer({ environment = "development" } = {}) { let server = createServer({ environment, models: { organization: Model, // 定义组织模型 }, serializers: { application: RestSerializer, // 使用 RestSerializer 进行序列化 }, routes() { this.namespace = 'api'; // 设置命名空间 // 获取所有组织 this.get('/organizations', (schema) => { return schema.organizations.all(); }); // 创建新组织(可以不限制层级) this.post('/organizations', (schema, request) => { let attrs = JSON.parse(request.requestBody); return schema.organizations.create(attrs); }); // 删除组织,若存在子组织则无法删除 this.delete('/organizations/:id', (schema, request) => { let orgId = request.params.id; let organization = schema.organizations.find(orgId); let children = schema.organizations.where({ parentId: orgId }); if (children.length > 0) { return new Response(400, {}, { error: 'Cannot delete organization with children' }); } else { organization.destroy(); return new Response(204); } }); // 更新组织信息 this.put('/organizations/:id', (schema, request) => { let orgId = request.params.id; let newOrgAttrs = JSON.parse(request.requestBody); let organization = schema.organizations.find(orgId); organization.update(newOrgAttrs); return organization; }); // 初始化默认数据 this.post('/initializeData', () => { schema.organizations.create({ id: 1, name: '总公司', description: '这是总公司', location: '北京', floor: 1, parentId: null, level: 1 }); schema.organizations.create({ id: 2, name: '分公司1', description: '这是分公司1', location: '上海', floor: 2, parentId: 1, level: 2 }); schema.organizations.create({ id: 3, name: '部门1', description: '这是部门1', location: '办公楼A', floor: 3, parentId: 2, level: 3 }); return new Response(200); }); }, }); return server; } // 创建 MirageJS 服务器 let server = makeServer(); // 使用示例 // 获取所有组织 axios.get('/api/organizations').then((response) => { console.log(response.data); }).catch((error) => { console.error(error); }); // 创建新组织 axios.post('/api/organizations', { name: '子公司1', description: '这是子公司1', location: '广州', floor: 4, parentId: 1, level: 2 }).then((response) => { console.log(response.data); }).catch((error) => { console.error(error); }); // 删除组织 axios.delete('/api/organizations/3').then((response) => { console.log('Organization deleted successfully'); }).catch((error) => { console.error(error); }); // 更新组织信息 axios.put('/api/organizations/2', { name: '分公司A', description: '这是分公司A', location: '上海', floor: 5, parentId: 1, level: 2 }).then((response) => { console.log(response.data); }).catch((error) => { console.error(error); }); // 初始化默认数据 axios.post('/api/initializeData').then((response) => { console.log('Default data initialized'); }).catch((error) => { console.error(error); });
场景描述:
产品列表和数据列表关联,一个产品,可以关联多个设备id,设备列表可以查看属于哪个产品信息
两个数据列表的增删改查,若产品列表有设备,则无法直接删除产品
创建设备的时候,需要关联对应的产品
查看设备的时候,需要有对应产品的信息
根据产品id能查到当前产品信息及产品下的所有设备列表
import { createServer, Model, RestSerializer, belongsTo, hasMany } from 'miragejs'; export function makeServer({ environment = "development" } = {}) { let server = createServer({ environment, models: { product: Model.extend({ devices: hasMany('device'), }), device: Model.extend({ product: belongsTo(), }), }, serializers: { application: RestSerializer, }, routes() { this.namespace = 'api'; // 获取产品列表 this.get('/products', (schema) => { return schema.products.all(); }); // 创建产品 this.post('/products', (schema, request) => { let attrs = JSON.parse(request.requestBody); return schema.products.create(attrs); }); // 获取单个产品及其设备列表 this.get('/products/:id', (schema, request) => { let productId = request.params.id; let product = schema.products.find(productId); let devices = schema.devices.where({ productId: productId }); return { product, devices }; }); // 删除产品,如果有关联设备则禁止删除 this.delete('/products/:id', (schema, request) => { let productId = request.params.id; let product = schema.products.find(productId); if (product.devices.length > 0) { return new Response(400, {}, { error: 'Cannot delete product with associated devices' }); } else { product.destroy(); return new Response(204); } }); // 获取设备列表 this.get('/devices', (schema) => { return schema.devices.all(); }); // 创建设备,并关联到对应产品 this.post('/devices', (schema, request) => { let attrs = JSON.parse(request.requestBody); let productId = attrs.productId; let product = schema.products.find(productId); if (!product) { return new Response(404, {}, { error: 'Product not found' }); } delete attrs.productId; let device = schema.devices.create({ ...attrs, product }); return device; }); // 获取单个设备及其对应产品信息 this.get('/devices/:id', (schema, request) => { let deviceId = request.params.id; let device = schema.devices.find(deviceId); let product = schema.products.find(device.productId); return { device, product }; }); }, }); return server; }