项目介绍

项目:后台管理系统,包含用户管理、订单管理、商品管理等等
技术栈

  1. react - react函数组件+hooks
  2. redux - react-redux/redux-saga
  3. 组件库 - antd4.x.x
  4. TypeScript
  5. 脚手架 umi
  6. 数据可视化 antv
  7. fetch/axios
  8. 表格导入导出 xlsx

项目职责

  1. 负责项目中的用户管理、订单管理、权限管理等模块
  2. 负责项目后期的维护和更新

项目亮点

  1. 采用TypeScript来定义数据类型,让项目安全度进一步提高
  2. 采用umi,让项目开发效率提升

项目难点

  1. 项目迭代升级
  2. 数据可视化
  3. hooks的应用

    开发过程

    构建项目

    UmiJS
    项目初始目录和文件
    image.png

    day1 - 页面基本布局

  • 使用Umijs提供的插件 umijs/plugin-layout完成页面基本布局配置

image.png

day2 - 完成路由拓展配置

  • 使用Umijs提供的插件 umijs/plugin-layout完成路由拓展配置
    • 侧边栏菜单数据根据路由中的配置自动生成
    • 侧边栏菜单配置
    • 布局路由级别展示/隐藏相关配置
  • 完成Login页面布局
    • 登录表达使用antd组件库Form表单的登录框架

image.png
image.png
image.png
image.pngimage.png

day3 - 登录实现包含路由拦截和权限路由

分装常用函数

  • cookie

    1. export function setCookie(name: string, value: string | number, n: number) {
    2. const oDate = new Date()
    3. oDate.setDate(oDate.getDate() + n)
    4. document.cookie = name + '=' + value + ';expires=' + oDate
    5. }
    6. export function getCookie(name: string) {
    7. const str = document.cookie
    8. const arr = str.split('; ')
    9. for (let i = 0; i < arr.length; i++) {
    10. const newArr = arr[i].split('=')
    11. if (newArr[0] == name) {
    12. return newArr[1]
    13. }
    14. }
    15. }
    16. export function removeCookie(name: string) {
    17. setCookie(name, 1, -1)
    18. }
  • request

    tyarn add axios tyarn add qs @types/qs

  1. //todo 封装数据请求
  2. import axios from 'axios'
  3. import qs from 'qs'
  4. import * as cookie from './cookies'
  5. //todo 创建axios自定义实例
  6. const ins = axios.create({
  7. timeout: 20000,
  8. baseURL: 'http://59.110.226.77:5000/api/private/v1/'
  9. })
  10. //todo 创建axios拦截器
  11. ins.interceptors.request.use(
  12. (config) => {
  13. //todo 携带token
  14. // config.headers.common[] = token
  15. config.headers.common['Authorization'] = cookie.getCookie('token')
  16. return config
  17. },
  18. (error) => {
  19. return Promise.reject(error)
  20. }
  21. )
  22. //todo 封装request函数
  23. interface Options {
  24. url: string
  25. method?: string
  26. data?: any
  27. type?: string //用于区别我是post请求的那种方式
  28. }
  29. export default function request(options: Options) {
  30. const { url, method = 'get', data = {}, type = 'form' } = options
  31. switch (method.toUpperCase()) {
  32. case 'GET':
  33. return ins.get(url, { params: data })
  34. case 'POST':
  35. if (type === 'json') {
  36. //json提交
  37. return ins.post(url, data)
  38. }
  39. if (type === 'file') {
  40. //文件提交
  41. const p = new FormData()
  42. for (const key in data) {
  43. p.append(key, data[key])
  44. }
  45. return ins.post(url, p)
  46. }
  47. // 进行表单提交 必须转参数【qs】
  48. return ins.post(url, qs.stringify(data))
  49. case 'PUT':
  50. return ins.put(url, data)
  51. case 'DELETE':
  52. return ins.delete(url, { data })
  53. default:
  54. return ins.get(url, { params: data })
  55. }
  56. }

实现登录功能

使用Umijs提供的插件 umijs/plugin-dva整合dva数据流实现状态管理

  1. 组件通过connect函数得到dispatch
  2. 点击登录按钮执行dispatch激活model.ts中的effects中的getLogin

image.pngimage.png

  • 实现路由拦截 如果未登录重定向到登录页面

image.png

  • 实现权限路由(路由建权),控制对订单管理访问权限对设置,权限级别不够禁止访问

image.pngimage.png
这样,访问/orders,就通过 useAuth做权限校验,如果通过,渲染正常页面,否则渲染组件

day4 - userList组件布局、数据请求及列表渲染

业务逻辑难点:UserListTable组件的展示的三种情况

  1. 数据请求直接崩了 error
  2. 数据请求成功,因参数传递不符合要求,导致后端返回结果为null
  3. 数据请求成功,后端给了正常数据

image.png
antd key报错

image.png
image.png

day5 - 实现部分功能(添加用户、删除单个用户)

添加用户

image.png
image.png

删除单个用户

image.png
Delete的方法是打印 参数currentID的值
image.png
此时拿到了每个用户的ID,将ID当作参数发送删除单个用户的数据请求

image.png
红框取实时处理数据 数据库和页面同步

搜索

搜索功能的实现只需要在发送一次数据请求就好了
image.png

day6 - 状态切换

image.png
此时ChangeState方法打印的结果:
image.png
第一个参数为switch的组件的checked值,第二个参数是对应列表的User信息,将第一个参数和第二个参数的id值作为参数发送修改用户状态的数据请求