mockjs基础使用及其模块化开发实践

362 阅读1分钟

1. mockjs介绍

json-server存在什么问题?
  • 如果接口不符合RESTful的规范,就不能使用json-server
为何要使用mockjs?

在正常开发中,后台开发人员编写的接口往往都是更后才会编写完成,并且他们还需要编写对应的接口文档,此时,如果作为前端开发人员,一直等待后台开发人员的接口与接口文档才做页面的调试,项目整体进度将会推迟,所以,我们前端开发人员需要自力更生,模拟后台返回的数据。

概括来说:为了缩短前端项目的研发周期,让我们可以不用等待后台接口

什么是mockjs? 有什么用?

官网:mockjs.com/

一个用于 生成随机数据拦截 Ajax请求第三方包

2. 在vue中使用mockjs的准备工作

  1. 项目安装mock
npm install mockjs
  1. 项目中新建mock/index.js文件
//引入mock模块
import Mock from 'mockjs'
  1. 将mock文件在main.js中导入
import Vue from 'vue'
import App FROM './App.vue'
import './mock/index.js'Vue.config.productionTip = falsenew Vue({
    render:h => h(App),
}).$mount('#app')

3. mock生成随机数据

本小节代码均写在mock/index.js中,

在浏览器控制台中观察效果

生成字符串
  • 生成指定次数字符串
import Mock from 'mockjs'
const data = Mock.mock({
    "string|4":"哈哈"
})
  • 生成指定范围长度字符串
const data = Mock.mock({
"string|1-8":"哈哈"
})
生成文本
  • 生成一个随机字符串
const data = Mock.mock({
    "string":"@cword"
}) 
  • 生成指定长度和范围
const data = Mock.mock({
    string:"@cword(1)"
    str :"@cword(10,15)"
})
生成标题和句子
  • 生成标题和句子
const data = Mock.mock({
    title:"@ctitle(8)"
    sentence:"@csentence"
})
  • 生成指定长度的标题和句子
const data = Mock.mock({
    title:"@ctitle(8)"
    sentence:"@csentence(50)"
})
  • 生成指定范围的
const data = Mock.mock({
    title:"@ctitle(5,8)"
    sentence:"@csentence(50,100)"
})
生成段落
  • 随机生成段落
const data = Mock.mock({
  content:"@cparagraph()"
})
生成数字
  • 生成指定数字
const data = Mock.mock({
    "number|80":1
})
  • 生成范围数字
const data = Mock.mock({
    "number|1-99":1
})
生成自增id
  • 随机生成标识
const data = Mock.mock({
    id:"@increment"
})
生成姓名-地址-身份证
  • 随机生成姓名-地址-身份证
const data = Mock.mock({
    name:"@cname()"
    idCard:"@id()"
    address:"@city(true)"
})
随机生成图片
  • 生成图片:@image('200x100', '#50B347', '#FFF', '张三')
  • 参数1:图片大小
[
    '300*250','250*250','240*400','336*280'
    '180*150','720*300','468*60','234*60'
    '388*31','250*250','240*400','120*40'
    '125*125','250*250','240*400','336*280'
]
  • 参数2:图片背景色
  • 参数3:图片前景色
  • 参数4:图片格式
  • 参数5:图片文字
生成时间
  • @Date
  • 生成指定格式时间:@date(yyyy-MM-dd hh:mm:ss)

指定数组返回的参数

  • 指定长度:‘date|5’
  • 指定范围:'data|5-10'
const data = Mock.mock({
'list|50-99':[
        {
            name:'@cname'
            address:'@city(true)'
            id:'@increment()'
        }   
    ]
})
拓展

如何上面的这些类型还不能满足你的需要,我们可以使用extend进行扩展,diy你想要的数据,如下:

Mock.Random.extend({
  status: function () {
    const status = ['男', '女', '未知']
    return this.pick(status)
  }
})
​
​
var myStatus = Mock.Random.status();
var yourStatus = Mock.mock(“@sex”)

4. mock拦截请求

核心代码后续除非特别说明都写在mock/index.js中

测试代码均写在App.vue中

在浏览器中观察控制台输出

定义get请求
Mock.mock('/api/news', 'get', () => {
  return {
    code: 0,
    msg: '发起get请求成功,但数据是mock返回的'
  }
})
​
​
定义post请求
Mock.mock('/api/news', 'post', () => {
  return {
    code: 0,
    msg: '发起post请求成功,但数据是mock返回的'
  }
})
测试代码
import axios from 'axios'export default {
  async created () {
    const res = await axios.get('/api/news')
    console.log(res)
​
    const res1 = await axios.post('/api/news')
    console.log(res1)
  }
}

5. 实现新闻管理案例

分页的关键点
  • 请求参数

    • 页码 page
    • 每页记录数 page_size
  • 响应参数

    • 数据 : [{}, {}]
    • 总页面 / 总条数
获取新闻列表接口文档

接口地址::/api/news

接口参数:

  • page:页码
  • pagesize: 每页的条数

请求类型:get

返回的数据:

{
        code: 0,
        message:"获取新闻列表成功",
        list:[
        {
            "id":1,
            "title":"解忧杂货店",
            "content":"《解忧杂货店》是日本作家东野圭吾写作的长篇小说。2011年《小说野性时代》连载,于2012年3月由角川书店发行单行本",
            "img_url":"http://t15.baidu.com/it/u=2090705107,20534764&fm=224&app=112&f=JPEG?w=500&h=500&s=61D0718656561FFFE504A51703000067",
            "add_time":"1984-04-03 11:43:37"}
        ],
        total:50
    }
}
使用mock模拟获取新闻列表接口

测试代码

  async created () {
    // const res = await axios.get('/api/news')
    // console.log(res)
    // // axios.post()
​
    // const res1 = await axios.post('/api/news')
    // console.log(res1)
​
    const res2 = await axios({
      url: '/api/news',
      method: 'get',
      params: {
        page: 3,
        pagesize: 10
      }
    })
    console.log(res2)
  }

使用mock拦截和返回随机数据

import Mock from 'mockjs'// 1. 生成总的随机数据
const { list } = Mock.mock({
  'list|40': [{
    id: '@increment',
    title: '@ctitle',
    content: '@cparagraph(5, 20)',
    img_url: "@image('200x200', '#CCCCCC', '#FFFFFF', 'NEWS ITEM')"
  }]
})
​
console.log(list)
​
function getQueryParmas (url, key) {
  //  params:
  //      url: /api/news?page=1&pagesize=10
  //      key: page
  //  return: 1
  const queryString = url.split('?')[1]
  // 'page=1&pagesize=10'
  const params = queryString.split('&')
  // ['page=1', 'pagesize=10']
  for (let i = 0; i < params.length; i++) {
    const param = params[i]
    // 'page=1'   or   'pagesize=10'
    const [key1, value] = param.split('=') // ['page', 1]
    if (key1 === key) {
      return value
    }
  }
  return null
}
​
// 2. 拦截网络请求
//  /api/news?page=1&pagesize=10
Mock.mock(//api/news/, 'get', (options) => {
  console.log(options.url)
  // /api/news?page=1&pagesize=10
  const page = parseInt(getQueryParmas(options.url, 'page'))
  const pagesize = parseInt(getQueryParmas(options.url, 'pagesize'))
  const start = (page - 1) * pagesize
​
  return {
    code: 0,
    message: '获取新闻列表成功',
    list: list.slice(start, start + pagesize),
    total: list.length
  }
})
还可以尝试自己把增、删、改和查详情的接口给mock出来

6. 模块化开发

  1. 在mock文件夹下新建modules文件夹,并在文件夹下新建users.js和books.js

    image.png

其中books.js的代码如下

export default {
  '/api/books|get': (options) => {
    return {
      code: 0,
      message: '获取书本列表成功'
    }
  },
  '/api/books|post': (options) => {
    return {
      code: 0,
      message: '新增书本成功'
    }
  }
}

users.js的代码如下

export default {
  '/api/users|get': (options) => {
    return {
      code: 0,
      message: '获取用户列表成功'
    }
  },
  '/api/users|post': (options) => {
    return {
      code: 0,
      message: '新增用户成功'
    }
  }
}

2.修改mock/index.js中的代码如下

// 1. 导入Mock核心模块对象
import Mock from 'mockjs'// 2. 基础设置,如设置超时时间
Mock.setup({
  timeout: 400
})
​
// 3. 通过webpack提供的require.context方法集成其他模块
const files = require.context('./modules', true, /.js$/)
files.keys().forEach(key => {
  const item = files(key).default
  for (const [protocal, handler] of Object.entries(item)) {
    // console.log(protocal, cb)
    const [url, method] = protocal.split('|')
    Mock.mock(new RegExp(url), method, handler)
  }
})
  1. 测试代码
const res3 = await axios.get('/api/books?a=1')
console.log(res3)
​
const res4 = await axios.post('/api/books')
console.log(res4)
​
const res5 = await axios.get('/api/users')
console.log(res5)
​
const res6 = await axios.post('/api/users')
console.log(res6)