umijs
目录
一、umijs
umijs:开发文档:
umi=react+less+antd(实现按需加载)+umi-request+dva(react+redux-saga)
二、项目创建
(1)先在本地创建项目名字
mkdir myapp && cd myapp
(2)执行创建
$ yarn create @umijs/umi-app # 或 npx @umijs/create-umi-app
(3)下载依赖
yarn install
(4)启动项目
yarn start
三、(内置)less和antd
umijs内置了less和antd,无需再配置相关环境,直接使用就行
import s from './index.less';
import {Button} from "antd";
export default function IndexPage() {
return (
<div>
<h1 className={s.title}>Page index</h1>
<Button type='default'>按钮</Button>
</div>
);
配置主题色,只需要指定颜色就可以了,umirc.ts文件可以完成所有配置项
// umirc.ts
import { defineConfig } from 'umi';
export default defineConfig({
...
//配置antd的主题色
theme: {
'primary-color': '#ffa39e'
},
});
四、路由搭建
umi路由分两种,1、umirc配置式路由。2、约定式路由
配置式路由:
- 不用引入组件,component默认加载,一级路由出口不用配置,默认进入一级,二级通过
{props.children}
配置出口 - exact: umijs的路由默认都是精确匹配
- 有二级路由配置时候,外层路由匹配默认模糊匹配。这样设计的目的就是让我们路由能够进入到二级路由甚至更多嵌套路由
// umirc.ts
import { defineConfig } from 'umi';
export default defineConfig({
...
routes: [
{ exact: true, path: '/home', redirect: '/home/product' },//重定向
{ path: '/', component: '@/pages/home' },
{ path: '/login', component: '@/pages/Login' },
{
path: '/home', component: '@/pages/Home',
routes: [
{ exact: true, path: '/home', redirect: '/home/product' },
{ path: '/home/product', component: '@/pages/Product' }
],
},
{ component: '@/pages/404' } // 放在最后,没有psth属性,前面所有都不匹配就404
],
});
约定式路由:
- umi 提供的一种路由方式,无需搭建映射。文件系统就是路由系统(文件路由)。前提是按照官方给定的约束,来创建项目结构,且umirc中没有routes配置。路由会自动生成。
- [ ]包裹的文件名是动态路由参数名,见详情
被注册为路由的规则:
- 必须以
.js
、.jsx
、.ts
或.tsx
结尾的文件,内容必须有JSX元素,且不能是以test.ts
、spec.ts
、e2e.ts
结尾的测试文件 - 文件或目录不以
.
或_
开头 - 不是
components
和component
、utils
和util
下的文件
全局约定式路由:约定 src/layouts/index.tsx
为全局路由
嵌套路由:约定以 对应文件下_layout.tsx
为嵌套路由,
// src/**/_layout.tsx
import React from 'react'
export default function _layout(props:any) {
return (
<div>{props.children}</div>
)
}
五、路由
跳转及参数传递
import React from 'react'
import { Link, NavLink, useHistory } from "umi"
export default function Product(props:any) {
const history = useHistory()
const gotoPage = ()=>{
// props.history.push("/home/user?id=1")
history.push("/home/user?id=1")
history.push({
pathname:"/home/user",
query:{id:1}
})
}
return (
<>
<Link to="/home/user?id=1">点击跳转</Link>
<Link to="/home/user?id=1">点击跳转</Link>
<button onClick={gotoPage}>函数式跳转</button>
</>
)
}
路由参数获取
umi参数传递,不管是那种方式,默认已经封装为一个对象,直接获取使用
import React, { useEffect } from 'react'
import { useLocation, useParams } from "umi"
export default function User(props: any) {
const location = useLocation()
const params = useParams()
useEffect(() => {
console.log(location);
console.log(params);
}, [])
return (<div></div>)
}
路由权限
React开发中为了解决这个问题,自行封装高阶组件,动态生成Route组件。
umi 中使用wrappers属性,提供auth组件来处理
routes: [
{ path: '/', component: '@/pages/index' },
{
path: '/register', component: '@/pages/Register', wrappers: [
'@/wrappers/auth'
],
}
...
],
auth组件代码为
import { Redirect } from 'umi'
export default (props: any) => {
// const { isLogin } = useAuth(); // 自定义hook。
const isLogin = false
if (isLogin) {
return <div>{props.children}</div>;
} else {
return <Redirect to="/login" />;
}
}
六、网络请求
内置umi-request模块
底层采用的fetch来实现,语法: request.post("地址",{data:{}})
import React from 'react'
import request from "umi-request"
export default function Index() {
const fetchData = () => {
request.get("http://127.0.0.1:8002/users/geUserList")
.then(res=> {console.log(res); })
.catch(error=>{ console.log(error); })
}
return (
<button onClick={fetchData}>请求发送</button>
)
}
axios发送请求
axios相对内置 request 来说功能更丰富。比如请求拦截器、终端请求等等,一般使用axios
import React from 'react'
import request from "umi-request"
import axios from 'axios'
export default function Index() {
const axiosGetData = ()=>{
axios.get("http://127.0.0.1:8002/users/getAccountList2")
.then(res=>{ console.log(res); })
}
return (
<button onClick={axiosGetData}>axios请求</button>
)
}
七、数据管理内置 dva
react一般结合redux来完成数据仓库管理(react+redux+redux-thunk)
dva框架:react封装的框架,主要包括 react-redux、redux-saga。
在umi中,内置dva作为一个插件来进行数据管理
搭建
(1) 无需下载任何插件,src/models,models下的ts文件,默认会被加载为数据仓库(状态机)文件
默认文件名字就是命名空间名字。必须要指定命名空间
// src/models/userModel.ts
export default {
// 数据
state:{
userName:'神农'
},
// 处理异步请求
effects:{
},
// 存放 reducer 代码
reducers:{
initState(state:any, action:any){
state.count = action.payload
return state
}
}
}
(2)页面上使用状态机的数据
import {useDispatch,useSelector} from "umi"
const {userName} = useSelector(state=>{
console.log(state);
return state.userModel
})
//派发请求修改仓库数据
const changeUserName = ()=>{
// 派发action到reducer的时候,必须指定命名空间名字
dispatch({type: "userModel/initState",payload: '尝百草'})
}
const dispatch = useDispatch()
<p>{{userName}}</p>
<button onClick={changeUserName}>更新名字</button>
异步请求数据 effects
redux
默认没有异步请求模块,需要借助于中间件来实现
redux-thunk
:加强dispatch,在派发到reducer之前发送异步请求,得到结果赋值给 reducer
redux-saga
:也是用于处理异步请求的中间件,采用 iterator迭代器
与 generato
编程来实现异步请求
// src/models/userModel.ts
import { getAllUser } from "@/api/user"
export default {
// 数据
state:{
userName:'神农'
},
// 处理异步请求
effects:{
// generator语法代码,函数前加 *
*getAllUserSaga({payload}, {call,put}){
// 默认只能传递一个参数,如果多个参数,封装为对象传递过去
const res = yield call(getAllUser, payload);
yield put({type:"initUser",payload:res.data.data})
}
},
// 存放 reducer 代码
reducers:{
initState(state:any, action:any){
state.count = action.payload
return { ...state }
}
}
}
在函数有里面yield关键字来控制执行顺序。等待异步的结果
put方法来调用 dispatch ,派发给reducer,更新仓库数据
以上就是umi的简单使用,更多内容,查看开发文档