-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d3509b4
commit 3a5069e
Showing
4 changed files
with
343 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,6 @@ tags: readme | |
|
||
后来就建了自己的博客,每个月交钱给阿里云。 | ||
|
||
还是打算在上面记录一些技术、生活、感想。 | ||
打算在上面记录一些技术、生活、感想。 | ||
|
||
各位看官,请~ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
--- | ||
title: react-router 4 嵌套路由实现 | ||
date: 2018-05-13 | ||
tags: Javascript | ||
--- | ||
|
||
# 问题 | ||
|
||
我们没用使用官方提供的react-router-config,而是自己实现了一套。问题在于,自己实现的不支持嵌套路由,于是我周末想了想,进行了改造 | ||
|
||
<!--more--> | ||
|
||
## route | ||
想支持却没有嵌套功能的路由: | ||
|
||
```js | ||
const RoutesConfig = { | ||
'/index': { | ||
component: asyncComponent(() => import('../containers/Home')), | ||
}, | ||
'/a': { | ||
component: asyncComponent(() => import('../containers/A')), | ||
}, | ||
}; | ||
``` | ||
## usage | ||
|
||
```jsx | ||
<Switch> | ||
{ | ||
getRoutes(match.path, routesConfig).map((item) => { | ||
return (<Route | ||
path={item.path} | ||
key={item.key} | ||
component={item.component} | ||
/> | ||
); | ||
}) | ||
} | ||
</Switch> | ||
``` | ||
|
||
## map | ||
|
||
```js | ||
export function getRoutes(path, routesConfig) { | ||
const routes = Object.keys(routesConfig).filter((routePath) => | ||
routePath.indexOf(path) === 0 && routePath !== path); | ||
const routesArr = routes.map((item, key) => { | ||
return { | ||
path: item, | ||
key, | ||
component: routesConfig[item].component, | ||
}; | ||
}); | ||
return routesArr; | ||
} | ||
``` | ||
|
||
# 解决 | ||
首先,我觉得router的配置文件应该是一个数组,这样有顺序。其次,我看了上面 map 部分的代码,其实也是把它转化成数组来操作的。(我在尝试之后觉得用对象实在太麻烦,每用一次就要转义一次)。既然如此,我就直接用数组了。 | ||
|
||
## route | ||
|
||
```js | ||
const RoutesConfig = [ | ||
{ | ||
path: '/index', | ||
component: asyncComponent(() => import('../containers/Home')), | ||
}, | ||
{ | ||
path: '/a', | ||
component: asyncComponent(() => import('../containers/A')), | ||
children: [ | ||
{ | ||
path: '/a/b', | ||
component: asyncComponent(() => import('../containers/A/B')), | ||
}, | ||
], | ||
}, | ||
]; | ||
``` | ||
既然要实现嵌套路由,所以嵌套的部分必然也是通用的数据结构,这样才能进行调用。 | ||
|
||
## check | ||
|
||
原先的 map 我发现和 usage 部分有点重复,所以只保留一个校验功能 | ||
|
||
```js | ||
export const routeCheck = (path, routesConfig) => routesConfig.filter((item) => | ||
item.path.indexOf(path) === 0 && item.path !== path); | ||
``` | ||
|
||
## Usage | ||
|
||
```js | ||
renderRoute = (routes) => { | ||
if (!Array.isArray(routes)) { | ||
return null; | ||
} | ||
return routes.map((item) => { | ||
if (item.children && item.children.length > 0) { | ||
return (<div | ||
key={`${item.key}-has-children`} | ||
> | ||
<Route | ||
path={item.path} | ||
key={item.key || item.path} | ||
component={item.component} | ||
/> | ||
<Switch> | ||
{ | ||
this.renderRoute(item.children) | ||
} | ||
</Switch> | ||
</div>); | ||
} | ||
return (<Route | ||
path={item.path} | ||
key={item.key || item.path} | ||
component={item.component} | ||
/>); | ||
}); | ||
}; | ||
``` | ||
|
||
然后,问题就顺利解决了 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
--- | ||
title: react-router 4 按需加载 | ||
date: 2017-08-20 | ||
tags: [Javascript, react-router, react] | ||
--- | ||
|
||
根据官网文档:[https://reacttraining.com/react-router/web/guides/code-splitting](https://reacttraining.com/react-router/web/guides/code-splitting) | ||
|
||
首先得安装bundle-loader | ||
|
||
```sh | ||
yarn add bundle-loader | ||
``` | ||
<!--more--> | ||
|
||
根据官网文档,定义了一个Bundle的组件 | ||
|
||
```jsx | ||
import React, { Component } from 'react'; | ||
|
||
export default class Bundle extends Component { | ||
state = { | ||
// short for "module" but that's a keyword in js, so "mod" | ||
mod: null, | ||
}; | ||
|
||
componentWillMount() { | ||
this.load(this.props); | ||
} | ||
|
||
componentWillReceiveProps(nextProps) { | ||
if (nextProps.load !== this.props.load) { | ||
this.load(nextProps); | ||
} | ||
} | ||
|
||
load(props) { | ||
this.setState({ | ||
mod: null, | ||
}); | ||
props.load((mod) => { | ||
this.setState({ | ||
// handle both es imports and cjs | ||
mod: mod.default ? mod.default : mod, | ||
}); | ||
}); | ||
} | ||
|
||
render() { | ||
return this.state.mod ? this.props.children(this.state.mod) : null; | ||
} | ||
} | ||
``` | ||
加载组件的时候使用bundle-loader加载,并且将组件传入Bundle中,最后渲染使用renderRoutes方法就可以了 | ||
|
||
```js | ||
import React from 'react'; | ||
import { | ||
BrowserRouter as Router, | ||
} from 'react-router-dom'; | ||
import { renderRoutes } from 'react-router-config'; | ||
|
||
/* eslint-disable */ | ||
import Index from 'bundle-loader?lazy&name=index!app/components/Demo/Index'; | ||
import IndexContainer from 'bundle-loader?lazy&name=index!app/components/Demo/IndexContainer'; | ||
import ListContainer from 'bundle-loader?lazy&name=list!app/components/Demo/ListContainer'; | ||
import NotFound from 'bundle-loader?lazy&name=notfound!app/components/Demo/NotFound'; | ||
|
||
/* eslint-enable */ | ||
|
||
import Bundle from 'app/components/Demo/Bundle'; | ||
|
||
|
||
const routes = [ | ||
{ | ||
component: (props) => ( | ||
<Bundle load={Index}> | ||
{(Component) => <Component {...props}/>} | ||
</Bundle> | ||
), | ||
routes: [ | ||
{ | ||
path: '/', | ||
exact: true, | ||
component: (props) => ( | ||
<Bundle load={IndexContainer}> | ||
{(Component) => <Component {...props}/>} | ||
</Bundle> | ||
), | ||
}, | ||
{ | ||
path: '/list/:moduleName', | ||
exact: true, | ||
component: (props) => ( | ||
<Bundle load={ListContainer}> | ||
{(Component) => <Component {...props}/>} | ||
</Bundle> | ||
), | ||
}, | ||
{ | ||
path: '/form/:moduleName/:id', | ||
exact: true, | ||
component: (props) => ( | ||
<Bundle load={FormContainer}> | ||
{(Component) => <Component {...props}/>} | ||
</Bundle> | ||
), | ||
}, | ||
{ | ||
path: '/*', | ||
component: (props) => ( | ||
<Bundle load={NotFound}> | ||
{(Component) => <Component {...props}/>} | ||
</Bundle> | ||
), | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
export default ( | ||
<Router> | ||
{renderRoutes(routes)} | ||
</Router> | ||
); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
--- | ||
title: react-router-config 使用 | ||
date: 2017-08-25 | ||
tags: [react, Javascript, react-router] | ||
--- | ||
|
||
react-router升级4之后,要想使用config方式的路由模式,要么自己写一个函数遍历config,要么使用react-router-config | ||
|
||
[https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config](https://github.com/ReactTraining/react-router/tree/master/packages/react-router-config) | ||
|
||
react-router-config还是beta版本,其中有 renderRoutes 方法,其作用就是遍历你的routes,返回<Router>和<Switch> | ||
|
||
<!--more--> | ||
|
||
```js | ||
import React from 'react' | ||
|
||
import Switch from 'react-router/Switch' | ||
|
||
import Route from 'react-router/Route' | ||
|
||
const renderRoutes = (routes, extraProps = {}) => routes ? ( | ||
|
||
<Switch> | ||
|
||
{routes.map((route, i) => ( | ||
|
||
<Route key={i} path={route.path} exact={route.exact} strict={route.strict} render={(props) => ( | ||
|
||
<route.component {...props} {...extraProps} route={route}/> | ||
|
||
)}/> | ||
|
||
))} | ||
|
||
</Switch> | ||
|
||
) : null | ||
|
||
export default renderRoutes | ||
``` | ||
|
||
而对于config文件,是这样的写法 | ||
|
||
```js | ||
const routes = [ | ||
{ | ||
component: Index, | ||
routes: [ | ||
{ | ||
path: '/', | ||
exact: true, | ||
component: IndexContainer, | ||
}, | ||
{ | ||
path: '/list/:moduleName', | ||
exact: true, | ||
component: ListContainer, | ||
}, | ||
{ | ||
path: '/*', | ||
component: NotFound, | ||
}, | ||
], | ||
}, | ||
]; | ||
``` | ||
在使用时,需要用renderRoutes(routes) | ||
|
||
而且,如果是嵌套路由,那么父路由处也需要写这个渲染函数 | ||
|
||
比如在Index 组件里 | ||
|
||
```js | ||
import React from 'react'; | ||
import { renderRoutes } from 'react-router-config'; | ||
|
||
export default class extends React.PureComponent { | ||
|
||
render() { | ||
return ( | ||
<div className="index-page"> | ||
{renderRoutes(this.props.route.routes)} | ||
</div> | ||
); | ||
} | ||
} | ||
``` |