vue 使用mock模拟数据
- 安装依赖
cnpm install axios --save
cnpm install mockjs --save-dev
cnpm install json5 --save-dev
-
在根目录下,新建一个mock文件,且创建如下文件
-
utils.js
-
index.js
-
const Mock = require('mockjs')
const { param2Obj } = require('./utils')
// 模拟的数据接口
const home = require('./home')const mocks = [...home,
]
function mockXHR() {Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.sendMock.XHR.prototype.send = function() {if (this.custom.xhr) {this.custom.xhr.withCredentials = this.withCredentials || falseif (this.responseType) {this.custom.xhr.responseType = this.responseType}}this.proxy_send(...arguments)}function XHR2ExpressReqWrap(respond) {return function(options) {let result = nullif (respond instanceof Function) {const { body, type, url } = optionsresult = respond({method: type,body: JSON.parse(body),query: param2Obj(url)})} else {result = respond}return Mock.mock(result)}}for (const i of mocks) {Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))}
}module.exports = {mocks,mockXHR
}
- mock-server.js
const chokidar = require('chokidar')
const bodyParser = require('body-parser')
const chalk = require('chalk')
const path = require('path')
const Mock = require('mockjs')const mockDir = path.join(process.cwd(), 'mock')function registerRoutes(app) {let mockLastIndexconst { mocks } = require('./index.js')const mocksForServer = mocks.map(route => {return responseFake(route.url, route.type, route.response)})for (const mock of mocksForServer) {app[mock.type](mock.url, mock.response)mockLastIndex = app._router.stack.length}const mockRoutesLength = Object.keys(mocksForServer).lengthreturn {mockRoutesLength: mockRoutesLength,mockStartIndex: mockLastIndex - mockRoutesLength}
}function unregisterRoutes() {Object.keys(require.cache).forEach(i => {if (i.includes(mockDir)) {delete require.cache[require.resolve(i)]}})
}// for mock server
const responseFake = (url, type, respond) => {return {url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),type: type || 'get',response(req, res) {console.log('request invoke:' + req.path)res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond))}}
}module.exports = devServe => {var app = devServe.app// parse app.body// https://expressjs.com/en/4x/api.html#req.bodyapp.use(bodyParser.json())app.use(bodyParser.urlencoded({extended: true}))const mockRoutes = registerRoutes(app)var mockRoutesLength = mockRoutes.mockRoutesLengthvar mockStartIndex = mockRoutes.mockStartIndex// watch files, hot reload mock serverchokidar.watch(mockDir, {ignored: /mock-server/,ignoreInitial: true}).on('all', (event, path) => {if (event === 'change' || event === 'add') {try {// remove mock routes stackapp._router.stack.splice(mockStartIndex, mockRoutesLength)// clear routes cacheunregisterRoutes()const mockRoutes = registerRoutes(app)mockRoutesLength = mockRoutes.mockRoutesLengthmockStartIndex = mockRoutes.mockStartIndexconsole.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed ${path}`))} catch (error) {console.log(chalk.redBright(error))}}})
}
- 定义mock的数据
在 Vue 中使用 mock 进行接口模拟数据时,接口路径中的 .* 是一个正则表达式的匹配规则,表示该路径可以匹配任意字符(包括字母、数字、特殊字符等)。
通常情况下,.* 用于模拟具有动态参数的接口路径。例如,假设你的接口路径为 /api/user/:id,其中的 :id 表示一个动态参数,可以是任意字符。为了模拟这样的接口,你可以使用 /api/user/.* 来匹配任意字符的请求路径。
通过使用正则表达式的匹配规则 .*,你可以实现更加灵活的接口模拟,并根据不同的请求路径返回对应的模拟数据。
- mock/home.js
const Mock = require('mockjs')
module.exports = [{url: '/api/user/.*',type: 'get',response: config => {const id = config.url.split('/').pop();let info// 根据动态参数返回不同的模拟数据if (id == '1') {info = {name: 'Alice' };} else if (id == '2') {info = {name: 'Bob' };} else {info = {name: 'Unknown' };}return {code: 200,data: info}}},{url: '/api/users/info',type: 'get',response: config => {return Mock.mock({code: 200,message: '处理成功',data: {userName:'@cname()',id: "@id()"},})}}
]
-
在vue.config.js文件中使用mock数据
-
在vue页面调用
<script>
import axios from "axios"
export default {methods:{async getUserInfo() {let res = await axios.get("/api/users/info");console.log(res.data);},async getUserInfoById() {let res = await axios.get("/api/user/1");console.log(res.data);}}
</script>
其他配置
使用npm run serve:stage才调用mock数据,同理部署时打包命令为npm run build:stage为模拟数据
- 在main.js中
if (process.env.NODE_ENV === 'stage') {const { mockXHR } = require('../mock')mockXHR()
}
- package.json
"serve:stage": "vue-cli-service serve --mode stage","build:stage": "vue-cli-service build --mode stage",
- .env.stage
NODE_ENV = stage
# just a flag
ENV = 'stage'
VUE_APP_DEV_BASE_API= ''
VUE_APP_REQUEST_URL='https://xxxx'