vue项目中使用mock

1,319 阅读2分钟

前言

当后端接口还没有开发完毕的时候,我们又急需一份数据来展示看效果时应该怎么办呢?这时我们可以根据后端提供给我们的接口文档,来弄一份真的假数据来协助我们完成前端开发工作,一起来看看如何实现吧~


一、mock

1. 什么是mock?

mock:假的

前端程序员提到的mock数据的含义是:真的假数据

  • 真的:符合接口规范要求的。

  • 假数据:数据是人为创建出来的,不是真正的业务数据。

2. 使用场景

后端接口的开发速度跟不上前端的进度, 而前端要实现业务还必须依赖数据,前端为了保证开发进度就需要自己mock数据 ,保证业务能正常开发

3. 实现方式

本地启mock服务器:

  • 自己用express写接口
  • 本地用专门的mock服务

线上的mock服务器: mock

二、vue项目中如何使用?

1. 步骤

  • 安装依赖 项目根目录下打开任意终端,执行命令:npm install mockjs axios

  • src文件夹下新建mock文件夹,新建index.js文件

  • main.js中引入mock

  • 任意.vue结尾的文件中使用

2. 代码演示

代码如下(示例):

mock/index.js中

//引入mock模块
import Mock from 'mockjs'

// const data = Mock.mock({
//   'string|4': 'yx!'
// })
// console.log(data)

// Mock.mock('/api/get/user', 'get', () => {
//   return {
//     status: 200,
//     message: '获取新闻列表数据成功'
//   }
// })

// Mock.mock('/api/post/user','post',()=>{
//   return {
//       status: 200,
//       message: '添加新闻列表数据成功'
//   }
// })

const data = Mock.mock({
  'list|20-60': [
    {
      id: '@increment(1)',
      title: '@ctitle',
      content: '@cparagraph',
      add_time: '@date(yyyy-MM-dd hh:mm:ss)'
    }
  ]
})

// 删除
Mock.mock('/api/delete/news', 'post', options => {
  let body = JSON.parse(options.body)
  const index = data.list.findIndex(item => item.id === body.id)
  data.list.splice(index, 1)
  return {
    status: 200,
    message: '删除成功',
    list: data.list
  }
})

// 添加
Mock.mock('/api/add/news', 'post', options => {
  let body = JSON.parse(options.body)

  data.list.push(
    Mock.mock({
      id: '@increment(1)',
      title: body.title,
      content: body.content,
      add_time: '@date(yyyy-MM-dd hh:mm:ss)'
    })
  )

  return {
    status: 200,
    message: '添加成功',
    list: data.list
  }
})

// 含有分页的数据列表,有需要接受的参数要使用正则匹配
// /api/get/news?pagenum=1&pagesize=10
Mock.mock(/\/api\/get\/news/, 'get', options => {
  console.log(options)
  // 获取传递的参数pageindex
  const pagenum = getQuery(options.url, 'pagenum')
  // 获取传递的参数pagesize
  const pagesize = getQuery(options.url, 'pagesize')
  // 截取数据的起始位置
  const start = (pagenum - 1) * pagesize
  // 截取数据的终点位置
  const end = pagenum * pagesize
  // 计算总页数
  const totalPage = Math.ceil(data.list.length / pagesize)
  // 数据的起始位置:(pageindex-1)*pagesize  数据的结束位置:pageindex*pagesize
  const list = pagenum > totalPage ? [] : data.list.slice(start, end)

  return {
    status: 200,
    message: '获取新闻列表成功',
    list: list,
    total: data.list.length
  }
})

const getQuery = (url, name) => {
  const index = url.indexOf('?')
  if (index !== -1) {
    const queryStrArr = url.substr(index + 1).split('&')
    for (var i = 0; i < queryStrArr.length; i++) {
      const itemArr = queryStrArr[i].split('=')
      console.log(itemArr)
      if (itemArr[0] === name) {
        return itemArr[1]
      }
    }
  }
  return null
}

main.js

import Vue from 'vue'
import App from './App.vue'
import router from '@/router'

import './mock/index.js'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.config.productionTip = false

Vue.use(ElementUI)

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

App.vue中

<template>
  <div id="app">
    <!-- 头部 -->
    <h3 style="text-align: center">数据展示</h3>

    <!-- 添加 -->
    <el-row :gutter="20">
      <el-col :span="8"><el-input v-model="title" placeholder="请输入标题"></el-input></el-col>
      <el-col :span="8"><el-input v-model="content" placeholder="请输入内容"></el-input></el-col>
      <el-col :span="8"><el-button type="primary" @click="handelAdd">添加</el-button></el-col>
    </el-row>

    <!-- 表格 -->
    <template>
      <el-table :data="tableData" style="width: 100%">
        <!-- <el-table-column label="图片" width="120">
          <template v-if="tableData[0]"><img :src="tableData[0].img_url" width="100" height="100"/></template>
        </el-table-column> -->
        <el-table-column prop="title" label="标题" width="160"> </el-table-column>
        <el-table-column prop="content" label="内容"> </el-table-column>
        <el-table-column prop="add_time" label="时间" width="160"> </el-table-column>
        <el-table-column label="操作" width="160">
          <template slot-scope="scope">
            <el-button @click="handleDelete(scope.row.id)" type="danger">删除</el-button>
          </template>
        </el-table-column>
      </el-table>
    </template>

    <el-button type="primary" @click="prev">上一页</el-button>
    <el-button type="primary" @click="next">下一页</el-button>
  </div>
</template>
<script>
import axios from 'axios'
export default {
  data() {
    return {
      tableData: [],
      title: '',
      content: '',
      pagenum: 1,
      pagesize: 10,
      total: 0
    }
  },
  methods: {
    // 获取数据列表
    async getList() {
      // axios.get("/api/get/news").then(res => (this.tableData = res.data.list));
      const result = await axios.get('/api/get/news', { params: { pagenum: this.pagenum, pagesize: this.pagesize } })
      this.tableData = result.data.list
      this.total = result.data.total
    },

    // 删除
    async handleDelete(id) {
      const result = await axios.post('/api/delete/news', { id })
      console.log(result)
      this.getList()
    },

    // 添加数据
    async handelAdd() {
      if (!this.title || !this.content) {
        alert('请输入内容')
        return
      }

      const result = await axios.post('/api/add/news', {
        title: this.title,
        content: this.content
      })
      console.log(result)
      this.getList()
      this.title = ''
      this.content = ''
    },

    prev() {
      if (this.pagenum > 1) {
        this.pagenum--
        this.getList()
      }
    },

    next() {
      if (this.pagenum * this.pagesize < this.total) {
        this.pagenum++
        this.getList()
      } else {
        alert('没有更多的数据')
      }
    }
  },
  created() {
    this.getList()
  }
}
</script>

3. 效果展示

在这里插入图片描述


总结

All that ends well is well.