前言
- 某次听公开课看别人用这玩意,感觉很nb,稍微学一下。
umijs
安装运行
- 先不用cli构建,安装全局命令umi
cnpm install -g umi
- 使用
umi g page index
可以生成index页面。一共2个文件,一个是js一个是css。 - umi g 是 umi generate 的别名,可用于快速生成 component、page、layout 等,并且可在插件里被扩展,比如 umi-plugin-dva 里扩展了 dva:model,然后就可以通过
umi g dva:model foo
快速 dva 的 model。 - 每个js文件都是个路由,会导出成react组件。
- 下面就运行试试,修改package.json里的script命令为:
"scripts": {
"dev": "umi dev",
"build": "umi build",
"test": "umi test"
},
- 然后用npm run dev试试。根路径就会去访问index.js这个文件,再建个文件比如user,路径上加user即可访问到。
- 启动后会发现目录里多了个叫
.umi
的文件夹,里面就是umi扫描pages生成的文件,最主要的就是路由之类,可以看见在router文件里面,路由里需要哪个文件看的很清楚。它还把路由信息挂到window上了,直接使用window.g_routes可以看路由。里面有个patchRoutes是运行时修改路由,就是动态修改路由。
跳转路由
- 里面跳转路由方式差不多。
- 第一种方式就是使用Link。
import styles from './index.css';
import Link from 'umi/link'
export default function () {
return (
<div className={styles.normal}>
<h1>Page index</h1>
<Link to="/user">/user</Link>
</div>
);
}
- 跟通常使用react-router-dom的link一样。
- 还有种方法使用router进行跳转:
import styles from './user.css';
import router from 'umi/router'
export default function () {
console.log(router);
return (
<div className={styles.normal}>
<h1>Page user</h1>
<button onClick={() => router.push('/xcxc')}>push</button>
</div>
);
}
- 打印router可以看见有go goback goForward replace push这些方法,这个就是history的方法。
全局路由
- 约定 src/layouts/index.js 为全局路由,返回一个 React 组件,通过 props.children 渲染子组件。
- 这个全局路由,就是渲染别的路由前必须渲染的。
- pages需要放到src下,这样才能生效。
src/layouts/index.js
import Link from 'umi/link'
export default function (props) {
return (
<div >
<h1>layout</h1>
<Link to="/">/</Link>
<Link to="/user">/user</Link>
<div>{props.children}</div>
</div>
);
}
嵌套路由
- 嵌套路由有点像小型的全局路由。就是在这个路由下必须渲染这个组件。
- 约定是需要的目录下写个
_layout.js
文件。这个路由下的所有路由都会通过它来渲染。
src/pages/product/_layout.js
import Link from 'umi/link'
export default function (props) {
return (
<div >
<h1>productA</h1>
<Link to="/product/productA">/productA</Link>
<Link to="/product/productB">/productB</Link>
<div>{props.children}</div>
</div>
);
}
- src/pages/product/productA和B就不放了,一个样。出来的效果就是productA和B都会在这个props.chilren里渲染。
动态路由
- umi 里约定,带 $ 前缀的目录或文件为动态路由。
src/pages/product/$id.js
export default function (props) {
return (
<div >
ID:{props.match.params.id}
</div>
);
}
- 我们改一下_layout把跳转写出来:
import Link from 'umi/link'
export default function (props) {
return (
<div >
<h1>productA</h1>
<Link to="/product/productA">/productA</Link>
<Link to="/product/productB">/productB</Link>
<Link to="/product/1">/1</Link>
<Link to="/product/2">/2</Link>
<div>{props.children}</div>
</div>
);
}
- 这样点1或者点2都会指向$id那个组件,那个组件通过props.match.params.id拿到参数。需要别的可以把props打印出来看。
权限路由
- umi 的权限路由是通过配置路由的 Routes 属性来实现。约定式的通过 yaml 注释添加。
/**
* title: privatepage
* Routes:
* - ./PrivateRouter.js
*/
export default function (props) {
return (
<div >
<h1>Private page</h1>
</div>
);
}
./PrivateRouter.js
是相对于根目录的位置。就是跟package.json一个位置。- yaml注释必须顶格写,不能空一行或者import完再写这个。
- yaml语法格式化工具转换后发现其实是这个:
{ title: 'privatepage', Routes: [ './PrivateRouter.js' ] }
- 这个语法还是挺常用的,前面在docker配置里用过。
PrivateRouter.js
import { Route, Redirect } from 'react-router-dom'
export default ({ render}) => {
return (
<Route render={
(props) => localStorage.getItem('login') ? render(props) : <Redirect to='/' />
}>
</Route>
)
}
- 这个就是在访问Private page时会先走一遍PrivateRouter,里面有个条件渲染,如果localstorage里有login的键,那么就渲染请求的路径,否则就重定向回主页。
- 权限路由就这么多内容了。