umi-v3
React项目说明
https://v3.umijs.org/zh-CN/docs/getting-started
一.通过脚手架创建项目
cnpm i yarn tyarn -g
mkdir umi-app
cd umi-app
yarn create @umijs/umi-app
npx @umijs/create-umi-app
yarn start
如果运行时报错 ·
cannot find module 'umi'
,那么执行yarn add umi@3
二.熟悉目录和文件
1.mock
模拟数据 http://mockjs.com/
生成随机数据,拦截 Ajax 请求
- 前后端分离
让前端攻城师独立于后端进行开发
开发无侵入
不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据
数据类型丰富
支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
增加单元测试的真实性
通过随机数据,模拟各种场景。
用法简单
符合直觉的接口。
方便扩展
支持扩展更多数据类型,支持自定义函数和正则
2.src
- pages 页面 — 等同于vue脚手架中views,存放的就是页面组件
- index.less
- index.tsx 注意引入的less是局部生效的,使用
:global
放成全局的
3.editorconfig 编辑器配置
4.gitignore git上传的忽略文件
5.prettierignore 格式化忽略配置文件
6.prettierrc 格式化配置文件
7.umirc.ts 项目配置文件,类似vue的vue.config.js,老版本umi中config/config.js
8.package.json 项目记录文件
9.README.md 项目说明书
10.tsconfig.json ts的配置文件
11.typings.d.ts ts的声明文件,不声明不可以引入
如果代码提示:无法使用 JSX,除非提供了 “–jsx” 标志。修改tsconfig.json文件中的
“jsx”: “react-jsx”, 为 ‘“jsx”: “react”
三.搭建项目基本结构
查看umi提供的umi插件
https://v3.umijs.org/zh-CN/plugins/plugin-layout
1.构建时配置
可以通过配置文件配置 layout
的主题等配置, 在 config/config.ts
或者 umirc.ts
中这样写:
1 | import { defineConfig } from 'umi'; |
2.运行时配置
https://umijs.org/zh-CN/plugins/plugin-layout#%E8%BF%90%E8%A1%8C%E6%97%B6%E9%85%8D%E7%BD%AE
src文件夹下创建 app.tsx
1 | // src/app.tsx |
3.扩展路由配置
config/route.ts
1 | $ npx umi g page home/Index --typescript --less |
// config/route.ts
1 | // config/route.ts |
umirc.ts中配置路由
1 | import { defineConfig } from 'umi'; |
src/global.css
https://v3.umijs.org/zh-CN/docs/assets-css
1 | html, body, #root { |
发现并没有如文档中所说生效,将其通过app.tsx引入到最前面即可
src/app.tsx
1 | // src/app.tsx |
四.登录页面实现
使用ant-design-pro
1 | cnpm i @ant-design/pro-components @ant-design/pro-form -S |
移动端接口地址:http://121.89.205.189:3000/apidoc/
pc后台管理系统:http://121.89.205.189:3000/admindoc/
1 | // src/pages/login/Index.tsx |
五.mock数据
序号 | 接口地址 | 接口参数 | 返回结果 |
---|---|---|---|
1 | /admin/admin/login | {adminname: ‘’, password: ‘’} | { code: ‘10005’,message: ‘该账户未注册’ } { code: ‘10003’,message: ‘密码错误’ } { code: ‘200’,message: ‘登录成功’, data: { adminname: ‘’, token: ‘’} } |
https://v3.umijs.org/zh-CN/docs/mock
5.1 开启mock
1 | // .umirc.ts |
5.2 设置mock数据
5.2.1 设置登录接口
1 | // mock/admin.ts |
5.2.2 设置管理员列表接口
1 | $ yarn add mockjs @types/mockjs -S |
1 | // mock/admin.ts |
5.2.3 添加接口
1 | // mock/admin.ts |
六.封装axios
umi中必须使用axios请求数据吗?
不是,可以使用umi的插件: https://umijs.org/zh-CN/plugins/plugin-request
cnpm i axios store2 -S
// utils/request.ts
1 | // src/utils/request.ts |
封装数据请求 src/api/admin.ts
1 | // src/api/admin.ts |
七.dva数据流 - 状态管理器
https://v3.umijs.org/zh-CN/plugins/plugin-dva
- 内置 dva,默认版本是
^2.6.0-beta.20
,如果项目中有依赖,会优先使用项目中依赖的版本。 - 约定式的 model 组织方式,不用手动注册 model
- 文件名即 namespace,model 内如果没有声明 namespace,会以文件名作为 namespace
- 内置 dva-loading,直接 connect
loading
字段使用即可 - 支持 immer,通过配置
immer
开启
约定式的 model 组织方式
符合以下规则的文件会被认为是 model 文件,
src/models
下的文件src/pages
下,子目录中 models 目录下的文件src/pages
下,所有 model.ts 文件(不区分任何字母大小写)
1.配置
https://v3.umijs.org/zh-CN/plugins/plugin-dva#%E9%85%8D%E7%BD%AE
// umirc.ts
1 | // .umirc.ts |
2.dva数据流引入
约定式的 model 组织方式
符合以下规则的文件会被认为是 model 文件,
src/models
下的文件 - 常用 – 全局性的redux数据src/pages
下,子目录中 models 目录下的文件src/pages
下,所有 model.ts 文件(不区分任何字母大小写) - 常用 - 表示某个模块下的redux数据
3.配置登录模块dva
使用第三种使用dva的方式
src/pages/login/model.ts
1 | // src/pages/login/model.ts |
1 | // src/pages/login/index.tsx |
1 | // src/pages/login/model.ts |
得到服务器的响应,如果登录成功,应该将信息保存到本地并且跳转到系统的首页
4.测试状态
1 | // src/components/Header.tsx |
1 | // src/app.tsx |
八.头部 - 退出
1 | // src/components/Header.tsx |
九.产品列表 - 了解
mock产品列表数据
1 | // mock/pro.ts |
1.新增一个声明文件 pro.d.ts
*.d.ts 称之为 ts中的声明文件, 写代码时可以自动提示 数据类型
Src/pages/pro/pro.d.ts
1 | export interface IPro { |
2.构建关于产品管理的dva数据流
dva数据流有三种使用方式
- Src/models/*.ts. * 要和定义的模块的namespace保持一致。 —— 登录数据流
- src/pages/models/*.ts
1 | // src/api/pro.ts |
//src/models/pro.ts
1 | // src/models/pro.ts |
3.产品列表页面请求数据并且展示
https://procomponents.ant.design/components/table#%E5%88%97%E8%A1%A8%E5%B7%A5%E5%85%B7%E6%A0%8F
// src/pages/pro/index.tsx
1 | import { useEffect, useState } from 'react'; |
十.权限管理 -了解
https://v3.umijs.org/zh-CN/docs/routing#wrappers
设定权限校验的组件 auth.tsx
Src/wrappers/auth.tsx
1 | // src/wrappers/auth.tsx |
配置路由的权限
// 其实是登录的权限
1 | // config/route.ts |
左侧菜单权限
// src/access.ts
1 | // export default function() { |
本项目逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 // src/access.ts
export default function(initialState: any) {
if (initialState) {
const adminname = initialState
return {
canReadHome: adminname === 'admin' || adminname === 'editor',
canReadBannerList: adminname === 'editor',
canReadBannerAdd: adminname === 'editor',
canReadProList: adminname === 'admin',
canReadProSearch: adminname === 'admin'
};
} else {
return {}
}
}
// src/app.tsx
1 | import { |
本项目逻辑
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 // src/app.tsx
import React from 'react';
import './global.less';
import store2 from 'store2'
import {
BasicLayoutProps,
Settings as LayoutSettings,
} from '@ant-design/pro-layout';
import Header from './components/Header';
export const layout = ({
initialState,
}: {
initialState: { settings?: LayoutSettings; };
}): BasicLayoutProps => {
return {
rightContentRender: () => <Header/>,
footerRender: () => <footer >footer</footer>,
menuHeaderRender: undefined,
...initialState?.settings,
};
};
export async function getInitialState() {
// const data = await fetchXXX();
// res.data.data[0] === { checkedKeys, adminid, adminname, role }
return store2.get('adminname');
}
// config/routes.tsx
1 | // config/route.ts |
1 | import { Effect, ImmerReducer, history } from 'umi'; |
十二.轮播图相关
Src/pages/banner-manager/banner.d.ts
1 | export interface IBanner { |
Src/pages/banner-manager/list.tsx
1 | import * as React from 'react'; |
1.构建以及请求轮播图的数据
// services/banner.ts
1 | import request from './../utils/request' |
2.构建数据流
Dva 数据流的使用方式
src/models/*.ts
src/pages/models/*.ts
src/pages/model.ts
// src/pages/banner/banner.d.ts
1 | // 这是一个声明文件,可以将接口写入到说明文件中 |
// src/models/banner.ts
1 | import { getBannerList } from '@/api/banner' |
3.列表页面请求数据
1 | import * as React from 'react'; |
5.数据的删除
1 | import * as React from 'react'; |
6.添加轮播图数据
// src/pages/banner_manager/add.tsx
1 | import React, { useState, useRef } from 'react' |
// 配置路由
1 | export interface IChildRoute { |
十三.面包屑导航
// src/components/MyBreadcrumb/index.tsx
1 | import * as React from 'react'; |
// 页面中使用 以产品列表为例
1 | import React from 'react'; |
十四、管理员操作
详情见代码
编辑使用抽屉,添加使用对话框
token的使用 — 拦截器
1 | import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse, Method, AxiosError } from 'axios' |
十三作业:
需要自主完成管理员列表的相关功能
adminname
password
role 2 超级管理员。1管理员
十五.富文本编辑器的使用
https://braft.margox.cn/demos/basic
1 | cnpm i braft-editor -S |
创建页面以及路由
1.创建表单页面
Src/pages/editor/Rich.tsx
1 | import * as React from 'react'; |
1 | { |
可以使用markdown编辑器
https://gitee.com/uiw/react-markdown-editor#https://github.com/jaywcjlove/react-monacoeditor
s r c/pages/editor/MarkDown.tsx
1 | import * as React from 'react'; |
1 | export interface IChildRoute { |
十六.数据可视化
ECharts https://echarts.apache.org/zh/index.html
1.html中使用echarts
1 |
|
2.在react中使用echarts
1 | cnpm install echarts --save |
Src/pages/data-manager/echarts.tsx
1 | import React from 'react'; |
1 | { |
1 | import React from 'react' |
3.其余的数据可视化工具
highcharts https://www.highcharts.com.cn/ 使用方法类似于echarts,但是。。。。
antv https://antv.vision/ https://antv.gitee.io/zh/
react - https://charts.ant.design/
在 React / Vue / Angular 中使用 G2
基于 AntV 技术栈还有许多优秀的项目,在 React 环境下使用 G2,我们推荐使用 Ant Design Charts,BizCharts 和 Viser。这三个产品都是基于 G2 的 React 版本封装,使用体验更符合 React 技术栈的习惯,他们都与 AntV 有着紧密的协同,他们很快也将同步开源和发布基于 G2 4.0 的版本。Viser 除了 React 外,还提供了 Vue 和 Angular 不同的分发版本。
- Ant Design Charts 地址:https://charts.ant.design
- BizCharts 地址:https://bizcharts.net
- Viser 地址:https://viserjs.github.io/
自己写
D3.js自定义数据可视化
Access-token. Refresh-token
- vue里面有一个MVVM的模型,对此怎么理解?它有什么作用?
- 双向数据绑定怎么实现?
- 立即反映到视图层或模型层是怎么做到的?
- 简单实现一下双向数据绑定,用JS去实现,这个要怎么做?
- 它可以监听哪些事件?
- 有自己封装过vue组件吗?
- Vue组件之间参数传递
- 遇到跨域问题,是怎么处理的?
- 页面上有比较复杂的数据结构,页面的表格可能比较复杂,当我要修改其中内容提交的时候,需要将这些数据提交上去,这个表格可能是一个list,里面是个对象,对象里可能又有一些数组,这样多层嵌套的数据结构,页面处理的时候需要怎么做?需要注意些什么?(比如调一些接口,服务端接口去查询,然后给返回了一个这样的列表,你要再页面上去展示,需要做些什么?)
- 正常显示一个列表是怎么显示的?通过什么组件?
- 开发过程中对组件库不熟,平时用到一个组件的时候怎么办呢?去哪找这个组件?
- 平常你在工作当中你是怎么去找我现在要用一个什么组件来完成现在的工作,因为你说你没封装过组件,那工作当中就是找现成的组件用,那你是从哪找的?
- 举个例子讲讲你平常工作中某一个业务的开发过程,当时你拿到了一个什么样的需求,你是怎么去理解这个需求的?怎么去跟后端开发人员以及其他相关人员交互的,最后怎么去完成这个工作?
- 这些接口是你告诉后端你需要什么接口,还是后端人员告诉你他有什么接口,然后你来想页面上怎么用?
- 需求给过来是个什么样子,是文档还是原型图,还是一些其他的形式呢?
- 从原型图效果图到实际的页面,这中间切图的工作也是你们做的吗?
- 你的首页和详情页是两个不同的页面,你们是单页面模式还是多页面模式?(我回答的单页面)
- 那首页跟详情页你是怎么路由的
- 假如在首页定义了一个定时器,(你是单页面),跳转到详情页面去了后,定时器还会继续生效吗?是还在后台继续运行还是已经被销毁了?
- 会在生命周期哪个阶段销毁?
- destroy这个阶段其实有两个方法会被调用,beforeDestroy和destroyed,beforeDestroy里面一般会做什么事情?
说一下你工作中处理过最难的一个前端的问题是什么?