惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Google DeepMind News
Google DeepMind News
The Last Watchdog
The Last Watchdog
腾讯CDC
Apple Machine Learning Research
Apple Machine Learning Research
有赞技术团队
有赞技术团队
Last Week in AI
Last Week in AI
量子位
雷峰网
雷峰网
宝玉的分享
宝玉的分享
美团技术团队
阮一峰的网络日志
阮一峰的网络日志
博客园 - 叶小钗
P
Privacy International News Feed
NISL@THU
NISL@THU
V
V2EX
博客园 - 三生石上(FineUI控件)
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
IT之家
IT之家
T
Tor Project blog
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Threatpost
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
大猫的无限游戏
大猫的无限游戏
V
Vulnerabilities – Threatpost
V
Visual Studio Blog
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Hacker News
The Hacker News
Scott Helme
Scott Helme
H
Hacker News: Front Page
罗磊的独立博客
Hacker News - Newest:
Hacker News - Newest: "LLM"
K
Kaspersky official blog
S
Secure Thoughts
www.infosecurity-magazine.com
www.infosecurity-magazine.com
The Cloudflare Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
C
Cybersecurity and Infrastructure Security Agency CISA
小众软件
小众软件
月光博客
月光博客
人人都是产品经理
人人都是产品经理
AI
AI
Help Net Security
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
Webroot Blog
Webroot Blog
博客园 - 【当耐特】
PCI Perspectives
PCI Perspectives
A
Arctic Wolf

博客园 - Mc525

antv3 x6 基本语法-流程图(二) element ui el-form 表单错误 滚动可视区域 vue2 element ui el-table大数据处理无分页解决方案-分片加载 vue2 地图热力图 -下钻省市县 三级及地图资源文件 vue2 组件封装 el-select vue2 组件封装 el-input vue2 组件封装 el-date-picker 日期 vue2 scss sass 基础安装包、安装依赖报错 !!! vue2 封装组件使用 v-mode【el-radio,el-input】 Mac Jenkins 环境部署 vue2 按钮权限(七) vue2 换肤(六) vue2 项目实例 国际化(五) vue2 项目实例 动态路由菜单(四) vue2 项目实例 Layout布局(二) vue2 项目实例 项目初始化(一) vue2 项目架构--api.js(七) vue2 项目架构--vue.config.js(七) vue2 项目架构--main.js(六)
vue2 项目实例 Mock数据模拟(三)
Mc525 · 2025-09-19 · via 博客园 - Mc525

在 Vue 2 项目中,Mock.js 可以帮你快速模拟后端接口数据,支持两种主要方式:

方式一:前端拦截(不会产生真实网络请求)

方式二:通过 devServer.before(会产生真实请求,网络面板可见)

npm install mockjs axios --save-dev

创建 src/mock/index.js

const Mock = require('mockjs');
const userJson = require('./login/user.json')
Mock.mock( process.env.VUE_APP_BASE_API
+ '/vue-admin-template/user/login', 'post', userJson )

可以正则匹配

// 只在开发环境使用 Mock
if (process.env.NODE_ENV === 'development') {
  require('./mock/index.js');
}

image

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 mockLastIndex
  const { 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).length
  return {
    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 = app => {
  // parse app.body
  // https://expressjs.com/en/4x/api.html#req.body
  app.use(bodyParser.json())
  app.use(bodyParser.urlencoded({
    extended: true
  }))

  const mockRoutes = registerRoutes(app)
  var mockRoutesLength = mockRoutes.mockRoutesLength
  var mockStartIndex = mockRoutes.mockStartIndex

  // watch files, hot reload mock server
  chokidar.watch(mockDir, {
    ignored: /mock-server/,
    ignoreInitial: true
  }).on('all', (event, path) => {
    if (event === 'change' || event === 'add') {
      try {
        // remove mock routes stack
        app._router.stack.splice(mockStartIndex, mockRoutesLength)

        // clear routes cache
        unregisterRoutes()

        const mockRoutes = registerRoutes(app)
        mockRoutesLength = mockRoutes.mockRoutesLength
        mockStartIndex = mockRoutes.mockStartIndex

        console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`))
      } catch (error) {
        console.log(chalk.redBright(error))
      }
    }
  })
}

index.js

const Mock = require('mockjs')
const { param2Obj } = require('./utils')

const user = require('./user')
const table = require('./table')

const mocks = [
  ...user,
  ...table
]

// for front mock
// please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event).
function mockXHR() {
  // mock patch
  // https://github.com/nuysoft/Mock/issues/300
  Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
  Mock.XHR.prototype.send = function() {
    if (this.custom.xhr) {
      this.custom.xhr.withCredentials = this.withCredentials || false

      if (this.responseType) {
        this.custom.xhr.responseType = this.responseType
      }
    }
    this.proxy_send(...arguments)
  }

  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)
    }
  }

  for (const i of mocks) {
    Mock.mock(new RegExp(i.url), i.type || 'get', XHR2ExpressReqWrap(i.response))
  }
}

module.exports = {
  mocks,
  mockXHR
}

utils.js

/**
 * @param {string} url
 * @returns {Object}
 */
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
}

module.exports = {
  param2Obj
}

user.js

const tokens = {
  admin: {
    token: 'admin-token'
  },
  editor: {
    token: 'editor-token'
  }
}

const users = {
  'admin-token': {
    roles: ['admin'],
    introduction: 'I am a super administrator',
    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
    name: 'Super Admin'
  },
  'editor-token': {
    roles: ['editor'],
    introduction: 'I am an editor',
    avatar: 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
    name: 'Normal Editor'
  }
}

module.exports = [
  // user login
  {
    url: '/vue-admin-template/user/login',
    type: 'post',
    response: config => {
      const { username } = config.body
      const token = tokens[username]

      // mock error
      if (!token) {
        return {
          code: 60204,
          message: 'Account and password are incorrect.'
        }
      }

      return {
        code: 20000,
        data: token
      }
    }
  },

  // get user info
  {
    url: '/vue-admin-template/user/info\.*',
    type: 'get',
    response: config => {
      const { token } = config.query
      const info = users[token]

      // mock error
      if (!info) {
        return {
          code: 50008,
          message: 'Login failed, unable to get user details.'
        }
      }

      return {
        code: 20000,
        data: info
      }
    }
  },

  // user logout
  {
    url: '/vue-admin-template/user/logout',
    type: 'post',
    response: _ => {
      return {
        code: 20000,
        data: 'success'
      }
    }
  }
]

vue.config.js

  productionSourceMap: false,
  devServer: {
    port: port,
    open: true,
    overlay: {
      warnings: false,
      errors: true
    },
    before: require('./mock/mock-server.js')
  },