vue3+vite+mockjs模拟数据

2,113 阅读3分钟

前言:前面文章写过vue3+vite+ts项目搭建,今天我们来学习如何用mockjs模拟数据

1.环境准备

1.安装依赖

npm install mockjs

2.模拟数据准备(此处为本地创建模拟数据,也可mock生成模拟数据)

在src文件夹下创建mock文件夹,用json文件保存模拟数据

[
    {
       "id": "1",
       "name": "张三",
       "age": 25,
       "sex": "男",
       "phone": "13254102121",
       "address": "湖北武汉"
    },
    {
        "id": "2",
        "name": "李四",
        "age": 18,
        "sex": "女",
        "phone": "13654102121",
        "address": "湖北武汉"
     },
     {
        "id": "3",
        "name": "王五",
        "age": 20,
        "sex": "女",
        "phone": "15854102121",
        "address": "湖北武汉"
     }
]

3.mock数据

在src/mock文件夹下创建index.ts文件,用于配置mock

import Mock from "mockjs";
import userList from "./user.json";

// 模拟数据生成
const data = Mock.mock({
    "data|5": [
        {   // 生成id,自增10,起始值为100
            "id|+10": 100,
            // 随机生成姓名(中文)
            "name": "@cname",
            "phone": /^1(3|4|5|6|7|8|9)[0-9]\d{8}$/,
            // 随机生成邮箱
            "email": "@email"
        }
    ]
})

// 获取用户数据(数据从user.json文件获取)
Mock.mock("/mock/users", {code: 200, data: userList});

// 获取用户数据(数据模拟生成)
Mock.mock("/mock/listMock", {
    code: 200, "data|5-10": [
        {   // 生成id,自增10,起始值为100
            "id|+10": 100,
            // 随机生成姓名(中文)
            "name": "@cname",
            // 随机获取一个值
            "sex|1": ["男", "女"],
            // 随机生成年龄,值在18-35之间
            "age|18-35": 0,
            // 随机生成电话号码
            "phone": /^1(3|4|5|6|7|8|9)[0-9]\d{8}$/,
            // 随机生成城市名称
            "address": "@city"
        }
    ]
});

// 新增用户接口
Mock.mock("/mock/addMock", (options) => {
    const params = JSON.parse(options.body);
    data.data.unshift(
        {   
            "id": "@increment",
            "name": params.name,
            "phone": params.phone,
            "email": params.email
        }
    )
    return {
        code: 200, success: true, message: '添加成功'
    }
});

// 编辑用户接口
Mock.mock("/mock/updateMock", (options) => {
    const params = JSON.parse(options.body);
    data.data.map(item => {
        if(params.id === item.id) {
            item.name = params.name;
            item.phone = params.phone;
            item.email = params.email;
        }
    })
    return {
        code: 200, success: true, message: '修改成功'
    }
});

// 删除用户接口
Mock.mock("/mock/deleteMock", (options) => {
    const params = JSON.parse(options.body);
    const deleteIndex = data.data.findIndex(item => {
        return item.id === params.id
    })
    data.data.splice(deleteIndex, 1);
    return {
        code: 200, success: true, message: '删除成功'
    }
});

4.在main.ts中引入

// 引入mock/index.ts
import '@/mock/index'

5.封装axios

具体封装请看上篇文章vue3+vite+ts项目搭建

修改请求地址为/mock

// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  baseURL: '/mock',
  headers: {
    // 
  },
  // 超时
  timeout: 30000
})

2.接口管理

在创建src/api文件夹,统一管理接口,在api文件夹下创建user.ts文件,管理用户相关接口

import request from '@/utils/request'

// 查询用户列表(数据从本地json获取)
export function listUser() {
    return request({
        url: '/users',
        method: 'get',
    })
}

// 查询用户列表(数据mock生成)
export function listMock() {
    return request({
        url: '/listMock',
        method: 'get',
    })
}

// 新增用户(数据mock生成)
export function addMock(data) {
    return request({
        url: '/addMock',
        method: 'post',
        data: data
    })
}

// 编辑用户(数据mock生成)
export function updateMock(data) {
    return request({
        url: '/updateMock',
        method: 'post',
        data: data
    })
}

// 删除用户
export function deleteMock(data) {
    return request({
        url: '/deleteMock',
        method: 'post',
        data: data
    })
}

3.接口请求

1.获取模拟数据(数据从本地json文件获取)

<template>
    <div class="app-container">
        <el-table v-loading="loading" :data="userList">
            <el-table-column label="用户姓名" align="center" key="name" prop="name" />
            <el-table-column label="用户性别" align="center" key="sex" prop="sex" />
            <el-table-column label="用户年龄" align="center" key="age" prop="age" />
        </el-table>
    </div>
</template>

<script lang="ts" setup>
import { listUser } from "@/api/user";

const loading = ref(true);
const userList = ref([]);

/** 查询用户列表 */
function getList() {
    loading.value = true;
    listUser().then((res: any) => {
        loading.value = false;
        userList.value = res.data;
    });
};

getList();
</script>

请求结果如下图所示:

image.png

2.获取模拟数据(数据为mock生成)

/** 查询用户列表 */
function getListMock() {
    loading.value = true;
    listMock().then((res: any) => {
        loading.value = false;
        userListMock.value = res.data;
    });
};

getListMock();

请求结果如下图所示:

image.png

注意:mockjs只是拦截地址,直接返回mock数据,并不会发送真实请求,因此看不见network的请求

3.模拟新增数据(数据为mock生成)

    <el-table v-loading="loading" :data="userListMock">
            <el-table-column type="selection" width="50" align="center" />
            <el-table-column label="用户编号" align="center" prop="id" />
            <el-table-column label="用户姓名" align="center" prop="name" />
            <el-table-column label="联系电话" align="center" prop="phone" />
            <el-table-column label="邮箱" align="center" prop="email" />
            <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
                <template #default="scope">
                    <el-tooltip content="修改" placement="top">
                        <el-button type="text" icon="Edit" @click="handleUpdate(scope.row)">
                        </el-button>
                    </el-tooltip>
                    <el-tooltip content="删除" placement="top">
                        <el-button type="text" icon="Delete" @click="handleDelete(scope.row)"></el-button>
                    </el-tooltip>
                </template>
            </el-table-column>
        </el-table>
        
 <!-- 添加或修改用户对话框 -->
      <el-dialog :title="title" v-model="open" width="500px" append-to-body>
         <el-form ref="dataRef" :model="form" :rules="rules" label-width="80px">
            <el-row>
               <el-col :span="24">
                  <el-form-item label="用户姓名" prop="name">
                     <el-input v-model="form.name" placeholder="请输入用户姓名" maxlength="50" />
                  </el-form-item>
               </el-col>
               <el-col :span="24">
                  <el-form-item label="联系电话" prop="phone">
                     <el-input v-model="form.phone" placeholder="请输入联系电话" maxlength="11" />
                  </el-form-item>
               </el-col>
               <el-col :span="24">
                  <el-form-item label="邮箱" prop="email">
                    <el-input v-model="form.email" placeholder="请输入邮箱" maxlength="50" />
                  </el-form-item>
               </el-col>
            </el-row>
         </el-form>
         <template #footer>
            <div class="dialog-footer">
               <el-button type="primary" @click="submitForm">确 定</el-button>
               <el-button @click="cancel">取 消</el-button>
            </div>
         </template>
      </el-dialog>
      
 /** 新增用户按钮 */
function handleAdd() {
    reset();
    open.value = true;
    title.value = '新增用户';
}
      
/** 提交按钮 */
function submitForm() {
    proxy.$refs['dataRef'].validate((valid: any) => {
      if (valid) {
        addMock(form.value).then((response: any) => {
            proxy.$modal.msgSuccess('新增成功');
            open.value = false;
            getListMock();
         });
      }
   });
}

image.png

请求结果如下图所示:

image.png

4.模拟编辑数据(数据为mock生成)

/** 提交按钮 */
function submitForm() {
    proxy.$refs['dataRef'].validate((valid: any) => {
      if (valid) {
        const tip = form.value.id && form.value.id != 0 ? '修改成功' : '新增成功';
        if (form.value.id && form.value.id != 0) {
            updateMock(form.value).then(() => {
                proxy.$modal.msgSuccess(tip);
                open.value = false;
                getListMock();
            });
        } else {
            addMock(form.value).then(() => {
                proxy.$modal.msgSuccess(tip);
                open.value = false;
                getListMock();
            });
        }
      }
   });
}

修改前页面如下图所示: image.png

编辑页面如下图所示: image.png

修改成功如下图所示: image.png

5.模拟删除数据

/** 删除用户按钮 */
function handleDelete(row: any) {
    proxy.$modal.confirm('是否确认删除用户名称为"' + row.name + '"的数据项?').then(function () {
    return deleteMock(row);
  }).then(() => {
    getListMock();
    proxy.$modal.msgSuccess("删除成功");
  }).catch(() => { });
}

删除数据之前,如下图所示: image.png

删除成功之后,如下图所示: image.png