Mock is used to create fake data in a project. Mock provides the function of intercepting request response data mock. Mock (), but Mock intercepting makes it impossible to synchronize data in a Network and can only be printed through console, which is quite troublesome to use. At this point we can use the KOA local service and Mock the data. The front-end project will proxy the request to the KOA local service so that the data can be syndicated across the Network.

EMock use

Item ADDRESS: eMock, example address: use-emock.

Clone the eMock project locally, create a new folder in the front-end project such as eMock, copy all the eMock project files except.git and node_modules to the eMock folder in the front-end project. Yarn Dev starts the service on port 8888. Then configure the proxy directly in the front-end project. Here is how to configure the project created on the CLI:

Vue. Config. Js file:

module.exports = { ...... .devServer: {
    proxy: {
      '/api': {
        target: 'http://localhost:8888'.ws: true.changeOrigin: true}}}... . }Copy the code

EMock profile

EMock uses KOA + Mock to generate Mock data, Nodemon –watch index –watch controller.js –watch global.js –watch./controllers/* The Nodemon can watch the file or folder. If the content is modified, restart the service.

Index.js entry file:

const Koa = require('koa')
const chalk = require('chalk')
const bodyParser = require('koa-bodyparser')

const global = require('./global.js').global
const controller = require('./controller')

const app = new Koa()

// Global public variables and methods
app.context.global = global

// log request URL:
app.use(async (ctx, next) => {
  console.log(chalk.blue(`Process ${ctx.request.method} ${ctx.request.url}. `))
  await next()
})

// parse request body:
app.use(bodyParser())

// add controllers:
app.use(controller())

app.listen(8888)
console.log(chalk.green('app started at port 8888... '))
Copy the code

The controller.js file automatically reads the js file in the controllers folder and automatically registers the router.

// https://github.com/michaelliao/learn-javascript/blob/master/samples/node/web/koa/url2-koa/controller.js

const fs = require('fs')
const chalk = require('chalk')

/**
 * add url-route in /controllers:
 * @param {Object} router require('koa-router')()
 * @param {Object} mapping require(__dirname + '/' + dir + '/' + f)
 */
function addMapping (router, mapping) {
  for (const url in mapping) {
    if (url.toLowerCase().startsWith('get ')) {
      const path = url.substring(4)
      router.get(path, mapping[url])
      console.log(chalk.green(`register URL mapping: ${chalk.yellow('get')} ${path}`))}else if (url.toLowerCase().startsWith('post ')) {
      const path = url.substring(5)
      router.post(path, mapping[url])
      console.log(chalk.green(`register URL mapping: ${chalk.yellow('post')} ${path}`))}else if (url.toLowerCase().startsWith('put ')) {
      const path = url.substring(4)
      router.put(path, mapping[url])
      console.log(chalk.green(`register URL mapping: ${chalk.yellow('put')} ${path}`))}else if (url.toLowerCase().startsWith('delete ')) {
      const path = url.substring(7)
      router.del(path, mapping[url])
      console.log(chalk.green(`register URL mapping: ${chalk.yellow('delete')} ${path}`))}else {
      console.log(chalk.red(`invalid URL: ${url}`))}}}/**
 * addControllers
 * @param {Object} router require('koa-router')()
 * @param {String} dir path
 */
function addControllers (router, dir) {
  fs.readdirSync(__dirname + '/' + dir).filter((f) = > {
    return f.endsWith('.js')
  }).forEach((f) = > {
    console.log(chalk.blue(`process controller: ${f}. `))
    const mapping = require(__dirname + '/' + dir + '/' + f)
    addMapping(router, mapping)
  })
}

module.exports = function (dir) {
  const controllers_dir = dir || 'controllers'
  const router = require('koa-router')()
  addControllers(router, controllers_dir)
  return router.routes()
}
Copy the code

If you have a convention that returns a different code value for different states, you can also put it in the global.js file:

/** stores public variables for all use */
class Global {
  global = {
    // After the first login, add the user to users, and then you can simulate the cookie automatic login
    users: [{cookie: 'cc077e4074d58b5b3afe96921b220364'.name: 'fxss'}].// Cookies of the logged-in user
    cookies: []}/** * Set cookie *@param {string} Val New cookie value */
  setCookie (val) {
    const cookies = this.global.cookies.concat(val)
    this.global.cookies = [...new Set(cookies)]
  }

  /** * delete cookie *@param {string} Val cookie value * /
  deleteCookie (val) {
    this.global.cookies.splice(this.global.cookies.indexOf(val), 1)}/** * Check whether the current cookie is in cookies *@param {string} Val Current cookie *@returns True: in the cookies. False: not in the cookies
  isInCookies (val) {
    return this.global.cookies.indexOf(val) ! = = -1
  }

  /** * get all public variables *@returns All public variables */
  getGlobal () {
    return this.global
  }

  /** * Use the current cookie to get user information *@param {string} Val Current cookie *@returns The user information corresponding to the current cookie */
  getUserByCookie (val) {
    let res = {}
    for (let index = 0, length = this.global.users.length; index < length; index++) {
      if (this.global.users[index].cookie === val) {
        res = this.global.users[index]
        break}}return res
  }
}

const global = new Global()

module.exports = {
  global
}
Copy the code

The public file is sufficient. Let’s look at the files in the controllers.

Login. js Login function:

const md5 = require('blueimp-md5')

// Login with a normal user name and password
const loginFn = async (ctx, next) => {
  const postData = ctx.request.body.data

  // This is just simulating the generation of cookies and then adding them to the public variable
  ctx.global.setCookie(md5(postData.password))
  ctx.response.type = 'json'
  ctx.response.body = ({
    user: {
      name: postData.name,
      cookie: md5(postData.password)
    }
  })
  next()
}

// Log in according to cookie
const loginByCookieFn = async (ctx, next) => {
  const user = ctx.global.getUserByCookie(ctx.cookies.get('mockCookie'))
  
  ctx.response.type = 'json'
  ctx.response.body = ({
    user: user
  })
  next()
}

module.exports = {
  'post /api/login': loginFn,
  'post /api/loginByCookie': loginByCookieFn
}
Copy the code

Logout.js Exits the function:

// Log out
const logoutFn = async (ctx, next) => {
  // Delete cookies in public variables
  ctx.global.deleteCookie(ctx.cookies.get('mockCookie'))
  ctx.response.type = 'json'
  ctx.response.body = ({
    msg: 'Exit successful'
  })
  next()
}

module.exports = {
  'post /api/logout': logoutFn
}
Copy the code

Then check the article’s additions, deletions, and changes:

const Mock = require('mockjs')
const Random = Mock.Random

// Generate the article increment id
const articles = Mock.mock({
  'list|100': [{
    'id|+1': 0}]})let articleList = articles.list

// Fill in the title, content, date, and author for the article
articleList = articleList.map(item= > {
  const title = Random.ctitle(3.10)
  const description = `${title}${Random.cparagraph()}`
  return {
    id: item.id === 0 ? 100 : item.id, The id of the new article is obtained from the id of the first article + 1
    title,
    description,
    time: Random.datetime('yyyy-MM-dd HH:mm:ss'),
    author: Random.cname()
  }
})

// Get the list of articles
const getArticlesFn = async (ctx, next) => {
  const currentPage = ctx.query.currentPage * 1
  const pageSize = ctx.query.pageSize * 1

  // Paging to get data
  const list = articleList.filter((item, index) = > index >= (currentPage - 1) * pageSize && index < currentPage * pageSize)
  ctx.response.type = 'json'
  ctx.response.body = ({
    list,
    total: articleList.length
  })
  next()
}

/** * Get the index * of the current article from the article id@param {string} Id Article ID *@returns Index */ of the current article
function getArticlesIndexById(id) {
  let res = -1
  for (let i = 0, len = articleList.length; i < len; i++) {
    if (articleList[i].id === id) {
      res = i
      break}}return res
}

// Get article details according to the article ID
const getArticlesByIdFn = async (ctx, next) => {
  const articleIndex = getArticlesIndexById(ctx.params.id * 1)

  // articleIndex! = 1
  ctx.response.type = 'json'
  ctx.response.body = ({
    article: articleList[articleIndex]
  })
  next()
}

// Add a new article
const postArticlesFn = async (ctx, next) => {
  const postData = ctx.request.body.data
  const id = articleList[0].id + 1articleList.unshift({ id, ... postData }) ctx.response.type ='json'
  ctx.response.body = ({
    msg: 'Added successfully'
  })
  next()
}

// Update the article
const putArticlesByIdFn = async (ctx, next) => {
  const articleIndex = getArticlesIndexById(ctx.params.id * 1)
  const postData = ctx.request.body.data
  articleList.splice(articleIndex, 1, postData)
  ctx.response.type = 'json'
  ctx.response.body = ({
    msg: 'Edit succeeded'
  })
  next()
}

// Delete the article
const deleteArticlesByIdFn = async (ctx, next) => {
  const articleIndex = getArticlesIndexById(ctx.params.id * 1)
  articleList.splice(articleIndex, 1)
  ctx.response.type = 'json'
  ctx.response.body = ({
    msg: 'Deleted successfully'
  })
  next()
}

module.exports = {
  'get /api/articles': getArticlesFn,
  'get /api/articles/:id': getArticlesByIdFn,
  'post /api/articles': postArticlesFn,
  'put /api/articles/:id': putArticlesByIdFn,
  'delete /api/articles/:id': deleteArticlesByIdFn
}
Copy the code