umijs 4.0学习 - 路由
1.umijs路由 - 配置路由
.umirc.ts 中配置路由router
import { defineConfig } from '@umijs/max';
export default defineConfig({antd: {},access: {},model: {},initialState: {},request: {},layout: {title: 'xxxxxx',},routes: [{path: '/',redirect: '/home',keepQuery: true //参数带过去},{name: '首页',path: '/home',component: './Home',},{name: '权限演示',path: '/access',component: './Access',},{name: '测试',path: '/ceshi',component: './Ceshi',},{name: ' CRUD 示例',path: '/table',component: './Table',},],npmClient: 'pnpm',
});
component: ‘./Table’, =====>
可以是绝对路径,也可以是相对路径。如果是相对路径,会从 src/pages 开始寻找。
如果指向 src 目录的文件,可以用 @,比如 component: ‘@/layouts/basic’,推荐使用 @ 组织路由文件位置。
这里配置的文件会在layout 导航中自动增加
2.path的支持种类
/groups
/groups/admin
/users/:id
/users/:id/messages
/files/*
/files/:id/*
3.子路由配置
routes: [{ path: '/login', component: 'login' },{name: ' Father 示例',path: '/Father',component: '@/pages/Father/index.tsx',routes: [{ path: 'ceshi', component: './Ceshi' }],},],
father
import { Outlet } from 'umi';const Father: React.FC = () => {return (<div style={{ padding: 20 }}><div>22222</div><Outlet /></div>);
};export default Father;
4.页面权限配置 wrappers
{name: ' CRUD 示例',path: '/table',component: './Table',wrappers: ['@/wrappers/auth'],},
auth.tsx
import { Navigate, Outlet } from 'umi';export default (props) => {// const { isLogin } = useAuth();if (true) {return <Outlet />;} else {return <Navigate to="/login" />;}
};
wrappers 中的每个组件会给当前的路由组件增加一层嵌套路由,如果你希望路由结构不发生变化,推荐使用高阶组件。先在高阶组件中实现 wrapper 中的逻辑,然后使用该高阶组件装饰对应的路由组件。
import { Navigate } from 'umi'const withAuth = (Component) => ()=>{const { isLogin } = useAuth();if (isLogin) {return <Component />;} else{return <Navigate to="/login" />;}
}
5.关闭layout layout: false,
{name: ' Father1',path: '/Father1',layout: false,component: '@/pages/Father1/index.tsx',},
6.约定式路由
除配置式路由外,Umi 也支持约定式路由。约定式路由也叫文件路由,就是不需要手写配置,文件系统即路由,通过目录和文件及其命名分析出路由配置。
如果没有 routes 配置,Umi 会进入约定式路由模式,然后分析 src/pages 目录拿到路由配置。
7.动态路由
8.在src下创建layouts 自定义导航
import { Outlet } from 'umi'export default function Layout() {return <Outlet />
}
9.404 路由
10.路由跳转以及参数传参
Link
<Link to="/users">Users Page</Link> 跳外链 用a标签
// 带参数
<Link to={{pathname: '/user',query: { id: 123, name: 'test' } // 会被转为 ?id=123&name=test
}}>用户页
</Link>
useNavigate
import { useNavigate } from 'umi';function MyComponent() {const navigate = useNavigate();const goToHome = () => {// 基本用法navigate('/home');// 带参数navigate('/user?id=123&name=test');// 或使用对象形式navigate({pathname: '/user',query: { id: 123 }});// 后退navigate(-1);// 前进navigate(1);};return <button onClick={goToHome}>去首页</button>;
}
useHistory 常用
import { useHistory } from 'umi';function MyComponent() {const history = useHistory();const goToAbout = () => {// 跳转到指定路由history.push('/about');history.push({pathname: '/user',query: { id: 123 }});// 替换当前路由(不会加入历史记录)history.replace('/about');// 后退history.goBack();// 前进history.goForward();};return <button onClick={goToAbout}>去关于页</button>;
}
获取参数
import { useSearchParams, useParams } from 'umi';function UserPage() {// 获取query参数const [searchParams] = useSearchParams();const id = searchParams.get('id'); // 适用于 ?id=123 形式// 获取动态路由参数const params = useParams();const userId = params.id; // 适用于 /user/:id 形式return <div>用户ID: {userId}</div>;
}// 导航时传递状态
navigate('/detail', { state: { from: 'list', data: { id: 1 } } });// 在目标页面接收状态
import { useLocation } from 'umi';function DetailPage() {const location = useLocation();const { from, data } = location.state || {};return <div>来自: {from}</div>;
}