> 文档中心 > Mockjs入门级操作 && 案例操作(实现增删改查功能) (二)

Mockjs入门级操作 && 案例操作(实现增删改查功能) (二)


Mockjs入门级操作 && 案例操作(实现增删改查功能) (二)

提示:上篇文章里讲解了 mockjs 的一些入门操作,及简单案例演示. 这篇文章将结合项目实现列表的增删改查功能.如有不当之处 欢迎指正


文章目录

  • Mockjs入门级操作 && 案例操作(实现增删改查功能) (二)
  • 前言
  • 一、回顾mockjs在vue项目中的基础使用步骤
  • 二、增删改查功能实现
    • 1.增删改查 -- 查
      • 1.创建views/list/index.vue :
      • 2.模拟 查询功能 的接口
      • 3.封装axios的列表接口
      • 4.views/list/index.vue中调用接口
      • 5. 处理分页功能
        • 1) options.url 解析参数值 :
        • 2) 对data数据进行处理
      • 6.完善list.vue页面的分页功能,使pageSize,currentPage 动态化
    • 2.增删改查 -- 增
      • 1. mockjs 模拟 新增 接口 ,封装axios的新增接口
      • 2. 创建 views/list/modules/listDialog.vue
      • 2.获取子组件传参,调用新增接口
      • 3. 完善 mockjs 的 新增接口
    • 3.增删改查 -- 改
      • 1. mockjs模拟 编辑 接口 ,封装 axios 的 编辑 接口
      • 2.点击编辑 , 将当前行数据传入listDialog
      • 3. listDialog 进行数据回显
      • 4. 点击编辑用户时,调用编辑接口
    • 4.增删改查 -- 删
        • 1.mockjs 模拟 删除 接口 , 封装 axios 的 删除接口
        • 2.点击删除时, 调用删除接口
  • 三. 完整代码 及 功能实现效果展示
    • 1. mock/list/index
    • 2. api/list/index
    • 3.views/list/index.vue
      • 4.
      • 5. 功能实现效果展示 :
  • 总结

前言

日常开发中,curd是每个项目都有的基础功能.下面实现在独立于后端时进行curd功能的实现


提示:以下是本篇文章正文内容,下面案例可供参考 如有不当之处 欢迎指正

一、回顾mockjs在vue项目中的基础使用步骤

  1. mock/list/index文件中对接口数据进行模拟;
  2. api/list/index 文件中封装axios请求
  3. .vue组件中调用接口,获取模拟数据;

二、增删改查功能实现

以下关于组件的创建不做过多赘述

1.增删改查 – 查

1.创建views/list/index.vue :

  1. 完成基本的分页列表布局;
    在这里插入图片描述

2.模拟 查询功能 的接口

  1. 生成列表的数据
  2. 生成 查询 功能的接口 ps :此处的 接口地址 需要与 axios 中封装的接口地址一致;
// 列表模拟数据生成//'userList|55': 数组的长度为55const data = Mock.mock({  'userList|55': [    {      id: '@increment',      name: '@cname()',      address: '@city(true)',      date: '@date(yyyy-MM-dd)'    }  ]})

data数据: 随机生成了长度为55的数组
在这里插入图片描述

生成 查询 功能的接口 :

  1. 此处 返回的格式需要和后端商讨一致.
    2.options : 可以接收到 本次请求的 Ajax 选项集
    RegExp : 对接口地址进行正则匹配.
// 生成 查询 功能的接口Mock.mock(RegExp('mock/userList'), 'get', (options) => {  console.log(options)  return {    code: 200,    success: true,    message: '获取用户列表成功',    data: data.userList,    totalPage: data.userList.length  }})

3.封装axios的列表接口

export const getUserListAPI = (params) => {  return request({    url: 'mock/userList',  // 此处的接口地址与模拟的 mockjs 接口地址一致    method: 'get',    params  })}

4.views/list/index.vue中调用接口

   async getUserList() {      const res = await getUserListAPI({ pageSize: this.pageSize, currentPage: this.currentPage      })      this.tableData = res.data      this.total = res.totalPage      console.log(res, 'res')    }

因为涉及到分页功能,所以需要传入 pageSize , currentPage 两个参数; 这时候再反过来看 options中获取到的数据,以及接口响应后我们模拟的返回数据
在这里插入图片描述
在这里插入图片描述

5. 处理分页功能

分页功能的处理 实际上就是对生成的data数据进行处理;

  1. 从 options.url中解析出 传过来的参数值 (pageSize,currentPage)
  2. 根据 pageSize(每页条数) currentPage(当前页) 处理 data数据
  3. 获取数据的起始值
  4. 获取数据的终止值
  5. 获取当前的总页数
  6. 返回新的数组

1) options.url 解析参数值 :

这里实际就是对 url 进行拆分,然后再匹配传入的值

// 处理get请求的url参数  "/api/api/mock/userList?pageSize=10&currentPage=1"const getQuery = (url, name) => {  const isFind = url.indexOf(name) !== -1  if (isFind) {    const queryArr = url.split('?')[1].split('&')    for (let i = 0; i < queryArr.length; i++) {      const result = queryArr[i].split('=')      if (result[0] === name) { return result[1]      }    }  }  return null}

2) 对data数据进行处理

完善mockjs的接口

Mock.mock(RegExp('mock/userList'), 'get', (options) => { // 根据url解析出pageSize的值  const pageSize = getQuery(options.url, 'pageSize')  // 根据url解析出currentPage的值  const currentPage = getQuery(options.url, 'currentPage')   /   * 对返回的数组进行处理 (即实现分页效果)   * 1.获取起始值  : pageSize=1 currentPage=10 即 0(索引)计算公式 : (pageSize-1)*currentPage   * 2.获取终止值  : pageSize=1 currentPage=10 即 9(索引)计算公式 : pageSize*currentPage (不-1,是因为使用splice进行截取;)   * 3.如当前页码超出总页码,则返回 [] ;计算公式 : totalPage=Math.ceil(data.length/currentPage)   */  const startIndex = (currentPage - 1) * pageSize  const endIndex = pageSize * currentPage  const totalPage = Math.ceil(data.userList.length / pageSize)  const newDataArr =    currentPage > totalPage ? [] : data.userList.slice(startIndex, endIndex)  return {    code: 200,    success: true,    message: '获取用户列表成功',    data: newDataArr,    totalPage: data.userList.length  }})

6.完善list.vue页面的分页功能,使pageSize,currentPage 动态化

 // 分页    handleSizeChange(val) {      this.pageSize = val      this.getUserList()    },    handleCurrentChange(val) {      this.currentPage = val      this.getUserList()    },  async getUserList() {      const { data, totalPage } = await getUserListAPI({ pageSize: this.pageSize, currentPage: this.currentPage      })      this.tableData = data      this.total = totalPage    }

分页功能展示 :
在这里插入图片描述

2.增删改查 – 增

1. mockjs 模拟 新增 接口 ,封装axios的新增接口

  1. mockjs 模拟 新增 接口 :

post请求,请求参数存在请求体里面;

Mock.mock(RegExp('mock/addUser'), 'post', (options) => {  console.log(options, 'options')  return {    code: 200,    success: true,    message: '用户添加成功'  }})``` 2. 封装axios的新增接口:```javascriptexport const addUserAPI = (data) => {  return request({    url: 'api/mock/addUser',    method: 'post',    data  })}

2. 创建 views/list/modules/listDialog.vue

  1. 完成基本的布局.

新增和编辑是共用的这个dialog弹框,所以弹框的title和btnText都是动态化的;

在这里插入图片描述
2. views/list/index.vue中引入listDialog ,实现弹框的显示隐藏功能:

// @handleOk="handleOk" --接收子组件传入的表单数据  // @ok="modelFormOk" 子组件修改完成,触发重新渲染列表 <list-dialog  ref="dialogFormVisible"  @handleOk="handleOk"  @ok="modelFormOk"/>  // 新增    handleAdd() {      this.$refs.dialogFormVisible.add()    },

listDialog :

  add() {      this.dialogFormVisible = true      this.btnText = '新增用户'      this.ruleForm = {}    },//弹窗关闭事件 onClose() {      this.dialogFormVisible = false    }
  1. 点击新增用户时,将获取的表单数据传入父组件中
 submitForm(formName) {      this.$refs[formName].validate(async (valid) => { if (valid) {   this.$emit('handleOk', this.ruleForm) } else {   return false }      })

2.获取子组件传参,调用新增接口

 async handleOk(formData) {      const res = await addUserAPI(formData)      if (res.success) { this.$message({   message: res.message,   type: 'success' }) this.$refs.dialogFormVisible.onClose() // 关闭弹窗 this.getUserList()  // 重新加载列表      }    },

3. 完善 mockjs 的 新增接口

此时已经将获取的表单数据传入了接口中, 这时再来看 post 传参 和 get 传参的不同之处,以及对data数据的处理;

post请求的参数 可以直接在 options.body中获取
因为获取到的数据是字符串形式("{“name”:“张三”,“address”:“成都”,“date”:“2022-03-01”}"),需要使用JSON.parse()进行转换
将当前传入的参数追加进 data列表中.

Mock.mock(RegExp('mock/addUser'), 'post', (options) => {  const params = JSON.parse(options.body)  data.userList.unshift(    Mock.mock({      id: '@increment',      name: params.name,      address: params.address,      date: params.date    })  )  return {    code: 200,    success: true,    message: '用户添加成功'  }})

新增功能展示 :
在这里插入图片描述

3.增删改查 – 改

1. mockjs模拟 编辑 接口 ,封装 axios 的 编辑 接口

1.mockjs模拟 编辑 接口

获取 传入的 id 值,进行匹配,重新赋值;

Mock.mock(RegExp('mock/editUser'), 'post', (options) => {  const params = JSON.parse(options.body)  for (let i = 0; i < data.userList.length; i++) {    if (data.userList[i].id === params.id) {      data.userList[i] = params    }  }  return {    code: 200,    success: true,    message: '用户修改成功'  }})

2.封装 axios 的 编辑 接口

export const editUserAPI = (data) => {  return request({    url: 'api/mock/editUser',    method: 'post',    data  })}

2.点击编辑 , 将当前行数据传入listDialog

handleEdit(record) {      this.$refs.dialogFormVisible.edit(record)    },

3. listDialog 进行数据回显

  edit(record) {      this.dialogFormVisible = true      this.ruleForm = Object.assign({}, record)      this.btnText = '编辑用户'    },

此处效果展示 :
在这里插入图片描述

在这里插入图片描述

4. 点击编辑用户时,调用编辑接口

实际上 ,此处和新增用户触发的是同一个方法
判断当前表单数据是否存在 id 值, 如果存在则是编辑, 不存在则是新增;
存在时 调用编辑接口
修改完成后,通知父组件已经完成修改,重新渲染列表

 submitForm(formName) {      this.$refs[formName].validate(async (valid) => { if (valid) {   if (!this.ruleForm.id) {     this.$emit('handleOk', this.ruleForm)   }   const res = await editUserAPI(this.ruleForm)   if (res.success) {     this.$message({message: res.message,type: 'success'     })     this.$emit('ok') // 完成修改,通知父组件重新渲染列表;     this.onClose()   } } else {   return false }      })    },

父组件 重新渲染事件 :

 // 编辑    modelFormOk() {      this.getUserList()    },

4.增删改查 – 删

1.mockjs 模拟 删除 接口 , 封装 axios 的 删除接口

  1. mockjs 模拟 删除 接口

获取传入的 id 值 ,进行匹配,查找到当前的索引;
通过Array.splice() 方法 删除当前数据

Mock.mock(RegExp('mock/deleteUser'), 'post', (options) => {  const params = JSON.parse(options.body)  const deleteIndex = data.userList.findIndex((item) => {    return item.id === params.id  })  data.userList.splice(deleteIndex, 1)  return {    code: 200,    success: true,    message: '用户删除成功'  }})
  1. 封装 axios 的 删除接口
export const deleteUserAPI = (data) => {  return request({    url: 'api/mock/deleteUser',    method: 'post',    data  })}

2.点击删除时, 调用删除接口

 // 删除    async handleDelete(record) {      const res = await deleteUserAPI(record)      if (res.success) { this.$message({   message: res.message,   type: 'success' }) this.getUserList()      }    },

效果展示 :
在这里插入图片描述

三. 完整代码 及 功能实现效果展示

1. mock/list/index

import Mock from 'mockjs'// 处理get请求的url参数const getQuery = (url, name) => {  const isFind = url.indexOf(name) !== -1  if (isFind) {    const queryArr = url.split('?')[1].split('&')    for (let i = 0; i < queryArr.length; i++) {      const result = queryArr[i].split('=')      if (result[0] === name) { return result[1]      }    }  }  return null}const data = Mock.mock({  'userList|55': [    {      id: '@increment',      name: '@cname()',      address: '@city(true)',      date: '@date(yyyy-MM-dd)'    }  ]})Mock.mock(RegExp('mock/userList'), 'get', (options) => {  const pageSize = getQuery(options.url, 'pageSize') // 根据url解析出pageSize的值  const currentPage = getQuery(options.url, 'currentPage') // 根据url解析出currentPage的值  /   * 对返回的数组进行处理 (即实现分页效果)   * 1.获取起始值  : pageSize=1 currentPage=10 即 0(索引)  计算公式 : (pageSize-1)*currentPage   * 2.获取终止值  : pageSize=1 currentPage=10 即 9(索引)  计算公式 : pageSize*currentPage (不-1,是因为使用splice进行截取;)   * 3.如当前页码超出总页码,则返回 [] ;  totalPage=Math.ceil(data.length/currentPage)   */  const startIndex = (currentPage - 1) * pageSize  const endIndex = pageSize * currentPage  const totalPage = Math.ceil(data.userList.length / pageSize)  const newDataArr =    currentPage > totalPage ? [] : data.userList.slice(startIndex, endIndex)  return {    code: 200,    success: true,    message: '获取用户列表成功',    data: newDataArr,    totalPage: data.userList.length  }})Mock.mock(RegExp('mock/addUser'), 'post', (options) => {  const params = JSON.parse(options.body)  data.userList.unshift(    Mock.mock({      id: '@increment',      name: params.name,      address: params.address,      date: params.date    })  )  return {    code: 200,    success: true,    message: '用户添加成功'  }})Mock.mock(RegExp('mock/deleteUser'), 'post', (options) => {  const params = JSON.parse(options.body)  const deleteIndex = data.userList.findIndex((item) => {    return item.id === params.id  })  data.userList.splice(deleteIndex, 1)  return {    code: 200,    success: true,    message: '用户删除成功'  }})Mock.mock(RegExp('mock/editUser'), 'post', (options) => {  const params = JSON.parse(options.body)  for (let i = 0; i < data.userList.length; i++) {    if (data.userList[i].id === params.id) {      data.userList[i] = params    }  }  return {    code: 200,    success: true,    message: '用户修改成功'  }})

2. api/list/index

import request from '@/utils/request.js'export const getUserListAPI = (params) => {  return request({    url: 'api/mock/userList',    method: 'get',    params  })}export const addUserAPI = (data) => {  return request({    url: 'api/mock/addUser',    method: 'post',    data  })}export const deleteUserAPI = (data) => {  return request({    url: 'api/mock/deleteUser',    method: 'post',    data  })}export const editUserAPI = (data) => {  return request({    url: 'api/mock/editUser',    method: 'post',    data  })}

3.views/list/index.vue

<template>  <div class="user-list-container">    <el-button type="primary" icon="el-icon-plus" @click="handleAdd">      新增用户    </el-button>    <el-table :data="tableData" style="width: 100%" height="450">      <el-table-column type="index" label="序号" width="50"> </el-table-column>      <el-table-column prop="date" label="日期"> </el-table-column>      <el-table-column prop="name" label="姓名"> </el-table-column>      <el-table-column prop="address" label="地址"> </el-table-column>      <el-table-column label="操作" width="100"> <template slot-scope="scope">   <el-button @click="handleEdit(scope.row)" type="text" size="small">     编辑   </el-button>   <el-popconfirm     title="确定删除此用户吗?"     @confirm="handleDelete(scope.row)"     confirm-button-text="确定"     cancel-button-text="取消"   >     <el-button type="text" size="small" slot="reference">删除     </el-button>   </el-popconfirm> </template>      </el-table-column>    </el-table>    <div class="pagination">      <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage" :page-sizes="[10, 20, 30, 40]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper" :total="total"      >      </el-pagination>    </div>    <list-dialog      ref="dialogFormVisible"      @handleOk="handleOk"      @ok="modelFormOk"    />  </div></template><script>import { getUserListAPI, addUserAPI, deleteUserAPI } from '@/apis/user.js'import ListDialog from './modules/ListDialog.vue'export default {  components: { ListDialog },  data() {    return {      tableData: [],      currentPage: 1,      pageSize: 10,      total: null    }  },  methods: {    handleEdit(record) {      this.$refs.dialogFormVisible.edit(record)    },    // 新增    handleAdd() {      this.$refs.dialogFormVisible.add()    },    async handleOk(formData) {      const res = await addUserAPI(formData)      if (res.success) { this.$message({   message: res.message,   type: 'success' }) this.$refs.dialogFormVisible.onClose()      }      this.getUserList()    },    // 编辑    modelFormOk() {      this.getUserList()    },    // 删除    async handleDelete(record) {      const res = await deleteUserAPI(record)      if (res.success) { this.$message({   message: res.message,   type: 'success' }) this.getUserList()      }    },    // 分页    handleSizeChange(val) {      this.pageSize = val      this.getUserList()    },    handleCurrentChange(val) {      this.currentPage = val      this.getUserList()    },    async getUserList() {      const { data, totalPage } = await getUserListAPI({ pageSize: this.pageSize, currentPage: this.currentPage      })      this.tableData = data      this.total = totalPage    }  },  created() {    this.getUserList()  }}</script><style lang="scss" scoped>.pagination {  margin-top: 10px;  text-align: right;}</style>

4.

<template>  <el-dialog :title="btnText" :visible.sync="dialogFormVisible" width="450px">    <el-form      :model="ruleForm"      :rules="rules"      ref="ruleForm"      label-width="100px"      class="demo-ruleForm"    >      <el-form-item label="姓名" prop="name"> <el-input v-model="ruleForm.name" style="width: 200px"></el-input>      </el-form-item>      <el-form-item label="地址" prop="address"> <el-input v-model="ruleForm.address" style="width: 200px"></el-input>      </el-form-item>      <el-form-item label="日期" required> <el-col :span="11">   <el-form-item prop="date">     <el-date-pickerv-model="ruleForm.date"placeholder="选择日期"value-format="yyyy-MM-dd"     >     </el-date-picker>   </el-form-item> </el-col>      </el-form-item>      <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">   {{ btnText }} </el-button> <el-button @click="onClose">取消</el-button>      </el-form-item>    </el-form>  </el-dialog></template><script>import { editUserAPI } from '@/apis/user'export default {  data() {    return {      dialogFormVisible: false,      ruleForm: { name: '', address: '', date: ''      },      rules: { name: [   { required: true, message: '请输入姓名', trigger: 'blur' },   { min: 2, max: 5, trigger: 'blur' } ], address: [   { required: true, message: '请输入居住地址', trigger: 'blur' } ], date: [   {     required: true,     message: '请选择日期',     trigger: 'blur'   } ]      },      btnText: null    }  },  methods: {    submitForm(formName) {      this.$refs[formName].validate(async (valid) => { if (valid) {   if (!this.ruleForm.id) {     this.$emit('handleOk', this.ruleForm)   }   const res = await editUserAPI(this.ruleForm)   if (res.success) {     this.$message({message: res.message,type: 'success'     })     this.$emit('ok')     this.onClose()   } } else {   return false }      })    },    add() {      this.dialogFormVisible = true      this.btnText = '新增用户'      this.ruleForm = {}    },    edit(record) {      this.dialogFormVisible = true      this.ruleForm = Object.assign({}, record)      this.btnText = '编辑用户'    },    onClose() {      this.dialogFormVisible = false    }  }}</script><style lang="less" scoped></style>

5. 功能实现效果展示 :

在这里插入图片描述


总结

提示:以上 使用 mockjs 前端独立实现 curd 功能 的完整代码 ,如有不当欢迎指正
以上的编辑功能可以在写在listDialog组件中 (因为我已经写完了就懒得修改了);