前端开发.模拟数据工具.mockjs

安装
npm install mockjs
用法demo
const Mock = require('mockjs')
const { mock } = Mock
const order = {
  good: [1, 5],
  date: '2019-07-24',
  name: '江小北',
  phone: '13677777777',
  price: '23.5',
  address: '地址'
}
module.exports = {
  // url 前缀
  prefix: 'demo',
  data: {
    'GET /order': async () => {
      return mock(order)
    },
    'POST /order': (data) => {
      Object.assign(order,data)
      return mock(order)
    }
  }
}
封装util
// 本文件被 node 使用,请勿使用 export/import
const Mock = require('mockjs')

const { Random } = Mock

/**
 * 查询工具类,用于在内存数组中查找符合条件的列表
 * @param {array} db
 * @param {number} limit 每页数量
 */
function Search(db, limit) {
  this.db = db || []
  this.limit = limit || 10
}
/**
 * 过滤器
 */
Search.prototype.filter = function(val, callback) {
  if (!callback) {
    callback = val
    this.db = this.db.filter(callback)
  } else {
    if (typeof val === 'string') {
      val = val.trim()
    }
    if (callback) {
      if (val !== undefined && val !== '') {
        this.db = this.db.filter(callback)
      }
    }
  }
  return this
}
/**
 * 排除一些字段输出
 */
Search.prototype.exclude = function(...keys) {
  this.db = this.db.map(item => {
    item = { ...item }
    keys.forEach(key => {
      delete item[key]
    })
    return item
  })
  return this
}
/**
 * 输出分页结果
 */
Search.prototype.pagination = function({ offset, limit }) {
  offset = parseInt(offset, 10) || 0
  limit = parseInt(limit, 10) || this.limit

  let db = this.db
  const total = db.length
  const start = Math.max(0, offset)
  const end = Math.min(limit + offset, total)

  db = db.slice(start, end)
  return {
    limit,
    offset: end,
    total,
    data: db
  }
}
/**
 * 返回结果数组
 */
Search.prototype.run = function() {
  return this.db
}

/**
 * 在数组中查找
 * @param {array} arr
 * @param {any} id 某个值
 * @param {string} key 键名
 */
function find(arr, id, key = 'id') {
  let index, item
  for (let i = 0; i < arr.length; i++) {
    // eslint-disable-next-line
    if (arr[i][key] == id) {
      index = i
      item = arr[i]
      break
    }
  }
  return {
    match: index !== undefined,
    index,
    data: item
  }
}

/**
 * 辅助 koa 输出异常
 * @param {Koa} ctx
 * @param {string} message 错误文本信息
 * @param {number} code HTTP 错误码
 */
function raise(ctx, message, code = 500) {
  ctx.status = code
  return {
    message
  }
}

/**
 * 输出一个乱序的数组
 * @param {arrya} arr
 */
function shuffle(arr) {
  const length = arr.length
  let index
  for (let i = length - 1; i; i--) {
    index = Math.floor(Math.random() * i)
    arr[i] = arr.splice(index, 1, arr[i])[0]
  }
  return arr
}

/**
 * 初始化一个长度为 count 的数组,用 0 填充
 * @param {number} count
 */
function initArray(count) {
  return new Array(count).fill(0)
}

/**
 * 经典增删改查
 * @param {string} name 命名空间
 * @param {array} db mock 的数据集
 * @param {string} key 主键名,默认 id
 */
function Classic(name, db, key = 'id') {
  this.name = name
  this.db = db
  this.key = key
}

/**
 * 创建一条数据
 */
Classic.prototype.create = function(callback) {
  return async ctx => {
    let data = ctx.request.body
    data[this.key] = Random.id()
    if (callback) {
      data = callback.call(this, data)
    }
    this.db.unshift(data)
    return data
  }
}

/**
 * 更新一条数据
 */
Classic.prototype.update = function(callback) {
  return async (ctx, id) => {
    const result = find(this.db, id, this.key)
    const { match, index } = result
    if (!match) {
      return raise(ctx, `${name}:${id} not found`)
    }
    let data = Object.assign(result.data, ctx.request.body)
    if (callback) {
      data = callback.call(this, data)
    }
    this.db[index] = data
    return this.db[index]
  }
}

/**
 * 获取一条数据
 */
Classic.prototype.retrieve = function(callback) {
  return async (ctx, id) => {
    const result = find(this.db, id, this.key)
    if (!result.match) {
      return raise(ctx, `${name}:${id} not found`)
    }
    let data = result.data
    if (callback) {
      data = callback.call(this, data)
    }
    return data
  }
}

/**
 * 删除一条数据
 */
Classic.prototype.delete = function() {
  return async (ctx, id) => {
    const { match, index } = find(this.db, id, this.key)
    if (match) {
      this.db.splice(index, 1)
    }
    return {}
  }
}

module.exports = {
  /**
   * 模拟延时,可以被 await
   * @param {number} ms 毫秒
   */
  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms))
  },
  /**
   * 在数组中查找,数组的元素有 id 属性
   * @param {array} arr
   * @param {number|string} id
   */
  find,
  /**
   * 为 koa 抛出异常
   * @param {Koa} ctx
   * @param {string} message
   * @param {number} code HTTP 状态码,默认 500
   */
  raise,
  /**
   * 数组乱序
   */
  shuffle,
  /**
   * 初始化一个长度为 n 的数组,每个元素用 0 填充
   */
  initArray,
  /**
   * 搜索
   */
  Search,
  /**
   * 快速创建经典的增删改接口(查询因为会根据条件变化较大,不纳入)
   * @param {string} name 目标
   * @param {array} db mock 存储
   * @param {string} key 主键名
   */
  classic(name, db, key = 'id') {
    const crud = new Classic(name, db, key)

    return {
      [`POST /${name}`]: crud.create(),
      [`GET /${name}/:id`]: crud.retrieve(),
      [`PUT /${name}/:id`]: crud.update(),
      [`DELETE /${name}/:id`]: crud.delete()
    }
  },
  Classic
}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容