018 Umi 中使用 mockjs 完善前后端分离

简介: 018 Umi 中使用 mockjs 完善前后端分离

在现在习惯的开发流程中,特别是快速交付流程里面,我们通常会在开始动工之前通过约定好 API 接口,然后前端通过使用 Mock 数据在本地模拟出 API 返回的正确的数据结构,完成全部的前端逻辑开发,然后在项目上线前修改请求路径到后端,如果双方都严格按照最开始的约定进行,并且在此期间没有任何的业务流程修改的话,那前端可能只需要简单的请求路径,就可以完成前后端连调工作。


在上一节课的练习中,我们采用了更原始的方法,直接在代码中写死数据,还要是一个列表,我们可以通过循环的方式来取巧生成。但是如果是一个对象,并且是一个大对象的话,那我们要么都用“11111”来渲染我们的整个页面,要么就要花大量的时间去编写“假数据”。


Umi 提供了开箱即用的 Mock 功能,能够用方便简单的方式来完成 Mock 数据的设置。



Mock 约定目录

Umi 约定 /mock 目录下的所有文件为 Mock 文件,每一个 mock 文件都会返回一个 default 对象,例如这样的目录结构:

.
├── mock
    ├── todos.ts
    ├── items.ts
    └── users.ts
└── src
    └── pages
        └── index.tsx
复制代码


/mock 目录中的 todos.ts, items.tsusers.ts 就会被 Umi 视为 Mock 文件 来处理。

值得注意的是 mock 目录下的文件的文件名对真正的 mock 服务不会产生任何的影响,所以你可以仅仅从业务的分类的角度来组织他们,甚至你讲所有的 mock 服务放在同一个文件中存放也可以。



Mock 文件

Mock 文件默认导出一个对象,而对象的每个 Key 对应了一个 Mock 接口,值则是这个接口所对应的返回数据,例如这样的 Mock 文件:

// ./mock/users.ts
export default {
  // 返回值可以是数组形式
  'GET /api/users': [
    { id: 1, name: 'foo' },
    { id: 2, name: 'bar' }
  ],
  // 返回值也可以是对象形式
  'GET /api/users/1': { id: 1, name: 'foo' },
}
复制代码

就声明了两个 Mock 接口,透过 GET /api/users 可以拿到一个带有两个用户数据的数组,通过 GET /api/users/1 可以拿到某个用户的模拟数据。



请求方式

当 Http 的请求方式是 GET 时,可以省略方法部分,只需要路径即可,例如:

// ./mock/users.ts
export default {
  '/api/users': [
    { id: 1, name: 'foo' },
    { id: 2, name: 'bar' }
  ],
  '/api/users/1': { id: 1, name: 'foo' },
}
复制代码


也可以用不同的请求方法,例如 POSTPUTDELETE

// ./mock/users.ts
export default {
  'POST /api/users': { result: 'true' },
  'PUT /api/users/1': { id: 1, name: 'new-foo' },
}
复制代码



关闭 Mock

Umi 默认开启 Mock 功能,如果不需要的话可以从配置文件关闭:

// .umirc.ts
export default {
  mock: false,
};
复制代码


或是用环境变量的方式关闭:

MOCK=none umi dev
复制代码


以上的内容大部分你可以在官网中找到,以下的内容是开发中的一些小 tip。如果你看到这个文章的时间较晚,那可能也能在官网中看到,因为这个系列的所有文档,后面会尽量整理到官网的内容中。



取到请求的参数

其实 Umi 中提供的 Mock 能力,本质上是一个 express 的中间件,你可以通过 req 取到请求的入参和 header 等信息。

import { Request, Response } from 'express';
export default {
  'POST /api/list': (req: Request, res: Response) => {
    const { body } = req;
    const { pageSize, offset } = body;
    // 从这里取出 pageSize, offset
    return res.json({
      success:true
    });
  },
}
复制代码



引入 Mock.js

上节课中我们手写了一个数据,有时候很尴尬的是取名困难,要让数据看起来好看一点,就要让数据重复的更少。

{
      id: i,
      title: "卡片列表",
      description:
        "Umi@4 实战教程,专门针对中后台项目零基础的朋友,不管你是前端还是后端,看完这个系列你也有能力合理“抗雷”,“顶坑”",
    }
复制代码


这时候我们可以引入一些现在流行的 Mock 数据的生成工具,比如 Mock.js ,来帮我们方便的生成随机的模拟数据,会让我们的模拟数据看起来更加真实。

类似上节课的练习数据,我们可以这么写。


import mockjs from "mockjs";
export default {
  "GET /api/list": mockjs.mock({
    "data|10": [{ id: "@id", title: "@name", description: "@cparagraph(2)" }],
  }),
};
复制代码


会自动生成类似如下数据,太长了,我这里摘录了两段,实际上生成了 10 个数据,这是通过 data|10 来指定的,你在表格数据中,可以给一个比较大的值来渲染一个超长列表。


{
  "data": [
    {
      "id": "810000197712245720",
      "title": "David Lewis",
      "description": "理史率能厂响命热么克积深先片。每号公状志山织声具接度通满被准。"
    },
    {
      "id": "230000199101266590",
      "title": "Sharon White",
      "description": "是石来验关且公决器重调受白设。农队战社五点团持老了取装场。"
    }
  ]
}
复制代码



实战

在上节课的技术上我们继续今天的实战。如果你不是每节课都看的朋友,你可以下载上节课的 源码归档



安装依赖

pnpm i mockjs @alita/plugins
复制代码


安装类型包

pnpm i @types/mockjs --D
复制代码


因为今天 Umi@4 正式发布,所以我们同步升级到 Umi@4

修改 packages.json 文件

- "@umijs/plugins": "4.0.0-rc.20",
+ "@umijs/plugins": "4.0.0",
- "umi": "4.0.0-rc.20"
+ "umi": "4.0.0"
复制代码

修改后,重新执行 pnpm i



新建 Mock 文件

新建 mock/list.ts,并写入如下内容:

import mockjs from "mockjs";
export default {
  "GET /api/list": mockjs.mock({
    success: true,
    "data|10": [
      {
        id: "@id",
        title: "@name",
        description: "@cparagraph(2)",
      },
    ],
  }),
};
复制代码



引入请求

详细内容在 14 课中已讲解,这里直接写使用。

修改配置文件 config/config.ts

import { defineConfig } from "umi";
export default defineConfig({
  // 最终值在插件中设置,所以这里不用写
  //   title: "Hello Umi",
  plugins: [
    require.resolve("@umijs/plugins/dist/model"),
    require.resolve("@umijs/plugins/dist/antd"),
+   require.resolve("@alita/plugins/dist/request"),
  ],
  model: {},
+ request: {},
  antd: {},
});
复制代码


src/pages/listcard/index.tsx 中引入请求,通过日志查看数据结构

import { useRequest, request } from "umi";
// 文件中原有内容略
const ListCard = () => {
  const { data } = useRequest(() => request("/api/list"));
  console.log(data);
  return (
  );
};
export default ListCard;
复制代码
{
    "data":[]
}
复制代码


修改原有的代码将 dataSource={[{}, ...data?.data]}data 作为 ListdataSource


image.png

源码归档



目录
相关文章
|
6月前
|
前端开发 JavaScript Java
前端 NUXT框架
前端 NUXT框架
86 0
|
6月前
|
JavaScript 小程序 API
【uniApp新模式: 使用Vue3 + Vite4 + Pinia + Axios技术栈构建】
【uniApp新模式: 使用Vue3 + Vite4 + Pinia + Axios技术栈构建】
592 0
|
存储 JavaScript 前端开发
“探索前后端分离架构下的Vue.js应用开发“
“探索前后端分离架构下的Vue.js应用开发“
108 0
|
JavaScript 前端开发 开发者
Vue工程化开发(脚手架环境)(上)
Vue工程化开发(脚手架环境)(上)
89 0
|
4月前
|
JavaScript 前端开发
【Vue3+TypeScript】CRM系统项目搭建之 — 关于如何设计出优质的 Vue 业务组件
【Vue3+TypeScript】CRM系统项目搭建之 — 关于如何设计出优质的 Vue 业务组件
50 0
【Vue3+TypeScript】CRM系统项目搭建之 — 关于如何设计出优质的 Vue 业务组件
|
4月前
【Vue3+TypeScript】CRM系统项目搭建之 — 路由配置
【Vue3+TypeScript】CRM系统项目搭建之 — 路由配置
28 0
|
4月前
|
缓存 JSON 安全
【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(一)
【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(一)
38 0
|
4月前
|
JavaScript API 数据处理
【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(二)
【Vue3+TypeScript】CRM系统项目搭建之 — Axiox 网络请求封装(二)
47 0
|
6月前
|
前端开发 JavaScript 中间件
koa开发实践2:为koa项目添加路由模块
koa开发实践2:为koa项目添加路由模块
135 0
|
缓存 JavaScript 前端开发
Vue工程化开发(脚手架环境)(下)
Vue工程化开发(脚手架环境)(下)
71 0
下一篇
无影云桌面