路由配置
什么是路由
<p>在点击导航选项的时候,让对应内容填充的到页面,实现这种效果的方式就是路由。简单来说,路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径来请求不同的资源。</p><p>在 umi 中,应用都是<a href="https://en.wikipedia.org/wiki/Single-page_application" target="_blank">单页应用</a>,页面地址的跳转都是在浏览器端实现的,不会去重新请求服务端获取 html。html 只是在应用初始化的时候加载一次。所有的页面都是由不同的组件构成,页面的切换其实就是不同组件的切换,你只需要在配置中把不同的路由路径和对应的组件关联上即可。单页应用的功能示意图如下:</p><p><img src="https://cdn.yuque.com/lark/0/2018/png/5482/1525691154758-08922bea-f29c-4d34-bade-e47fc0cce089.png#align=left&alt=image" style="max-width: 600px;"></p>
路由配置方法
<p>在 umi 应用中,路由的配置是在<code>/config/config.js</code>中 <code>exports.routes</code> 中配置。</p>
基本
<p><code>exports.routes</code> 需要是一个数组,数组中的每一个对象是一个路由信息,比如:</p>
exports.routes = [
{
path: '/',
component: 'App',
},
{
path: '/user',
component: 'User',
}
];
<p>其中,path 表示页面访问路径,component 表示 page 下的文件名,比如 <code>App</code>, <code>User</code> 分别表示 <code>page/App</code>,<code>page/User</code>。这样,访问 <a href="http://localhost:7001/" target="_blank">http://localhost:7001/</a> 和 <a href="http://localhost:7001/user" target="_blank">http://localhost:7001/user</a> 则会有展示 <code>App</code>, <code>User</code> 中的内容。</p>
routes
<p>当需要有一个 <code>layout</code> 作为展示,可以设置 <code>routes</code>:</p>
exports.routes = [
{
path: '/',
component: 'App',
routes: [{
path: 'list'
component: 'List',
}, {
path: 'admin'
component: 'Admin',
}]
},
{
path: '/user',
component: 'User',
}
];
<p>在 <code>page/App</code> 中:</p>
export default (props) => <div style="{{padding:" 20}}="">
{this.props.children}
</div>
<p>这样访问 <code>/list</code> 跟 <code>/admin</code> 将会都有这个 <code>layout</code>。</p><p>更多配置信息和路由使用方式请参考 umi 官方文档。</p>
实战配置
<p>我们已经知道了如何在 umi 中配置路由了,那么下面就来实操一把。</p>
第一步:创建页面组件
<p>根据侧边导航样式,我们在 <code>Dashboard</code> 这个目录层级下有三个页面组件需要创建。</p><p>在 <code>src/page</code> 文件夹下创建 <code>Dashboard</code> 文件夹,同时在该文件夹中新建 <code>Analysis.js</code>, <code>Monitor.js</code>, <code>Workplace.js</code> 三个文件,目录结构如下:</p>
.
├── Dashboard
│ ├── Analysis.js
│ ├── Monitor.js
│ └── Workplace.js
...// 省略其他章节中的目录
<p>三个文件中,我们分别添加简单的函数组件。</p>
// Analysis.js
export default () => {
return <h1>Analysis Page</h1>
}
// Monitor.js
export default () => {
return <h1>Monitor Page</h1>
};
// Workplace.js
export default () => {
return <h1>Workplace Page</h1>
};
第二步:配置应用路由
<p>在《初始化项目》一节中你已经用配置式路由添加了 <code>helloworld</code> 路由,这里在 config.js 中我们添加本章的三个路由:</p>
export default {
routes: [{
path: '/',
component: '../layout',
routes: [
{
path: '/',
component: 'Helloworld',
},
{
path: '/helloworld',
component: 'Helloworld'
},
{
path: '/dashboard',
routes: [
{ path: '/dashboard/analysis', component: 'Dashboard/Analysis' },
{ path: '/dashboard/monitor', component: 'Dashboard/Monitor' },
{ path: '/dashboard/workplace', component: 'Dashboard/Workplace' }
]
},
]
}],
};
<p>这段配置的意思是指:</p><ul><li> 访问 <code>/</code> 下面的路由的时,使用 <code>page</code> 文件夹下的 <code>../layout</code> 布局文件渲染页面,默认展示Helloworld组件 </li></ul><ul><li> 访问 <code>/dashboard/analysis</code> 时,使用 <code>page</code> 文件夹下的 <code>Dashboard/Analysis</code> 组件渲染到 layout 文件中 children 部分 </li></ul><ul><li> 访问 <code>/dashboard/monitor</code> 时,使用 <code>page</code> 文件夹下的 <code>Dashboard/Monitor</code> 组件渲染到 layout 文件中 children 部分 </li></ul><ul><li> 访问 <code>/dashboard/workplace</code> 时,使用 <code>page</code> 文件夹下的 <code>Dashboard/Workplace</code> 组件渲染到 layout 文件中 children 部分 </li></ul>
第三步:配置侧边栏导航
<p>万事俱备,只欠东风,路由已经和相应的页面组件关联起来了,现在我们只需要配置导航,使得能在点击导航时,触发 URL 刷新,路由根据配置返回和当前 URL 匹配的内容.</p><p>我们用 <code>Link</code> 组件(相当于<a>) 实现路由的跳转.</p>
import Link from 'umi/link';
...
<sider width="{256}" style="{{" minheight:="" '100vh'="" }}="">
<div style="{{" height:="" '32px',="" background:="" 'rgba(255,255,255,.2)',="" margin:="" '16px'}}="">
<menu theme="dark" mode="inline" defaultselectedkeys="{['1']}">
<menu.item key="1">
<link to="/helloworld">
<icon type="pie-chart">
<span>Helloworld</span>
</icon></menu.item>
<submenu key="sub1" title="{<span"><icon type="dashboard"><span>Dashboard</span>}
>
<menu.item key="2"><link to="/dashboard/analysis">分析页</menu.item>
<menu.item key="3"><link to="/dashboard/monitor">监控页</menu.item>
<menu.item key="4"><link to="/dashboard/workplace">工作台</menu.item>
</icon></submenu>
</menu>
</div></sider><p>页面效果如下:</p><p><img src="https://cdn.nlark.com/yuque/0/2018/png/85418/1537087681575-adae809a-6713-473f-b382-3f4596fe1a9b.png#alt=undefined" style="max-width: 600px;"></p>
结语
<p>至此我们的 demo 应用现在已经支持了最朴素的路由和布局了。实际项目中,我们会通过各种方式,优化整个布局和路由的实现过程(比如将导航菜单配置化,抽象出单独的侧边栏组件和顶部导航组件等),但最基本的原理与上面的简单应用是一样的。</p><p>那我们的侧边栏导航是不是至此就功能完备了呢?并没有,实际上还有很多的细节没有实现,比如当页面的url改变后导航要能够根据url路径的不同展开对应的导航菜单等,为了避免大家陷入到细节中,这里不做具体探讨,感兴趣的同学可以参考<a href="https://github.com/ant-design/ant-design-pro/" target="_blank">Ant Design Pro</a>的代码进行深入阅读。</p>