07 Rdoc(react-doc) BasicLayout.js
import React, { PureComponent } from 'react';
import { Switch, Link, Route, Redirect } from 'react-router-dom';
import classNames from 'classnames';
import styles from './BasicLayout.less';
import Header from '../component/Header';
import Footer from '../component/Footer';
import logo from '../rdoc.logo.svg';
function getCurrentArticle(routeData, path) {
let article = null;
routeData.forEach((item) => {
if (item.path === path) {
article = item.article;
}
});
return article;
}
export default class BasicLayout extends PureComponent {
constructor(props) {
super(props);
this.state = {};
}
componentDidUpdate() {
this.scrollToTop();
}
componentDidMount() {
this.scrollToTop();
}
scrollToTop() {
document.body.scrollTop = 0;
document.documentElement.scrollTop = 0;
window.scrollTo(0, 0);
}
renderSubMenuItem(menus) {
const { location: { pathname } } = this.props;
if (menus.length > 1) {
menus = menus.sort((a, b) => {
if (a.sort < b.sort) return -1;
if (a.sort > b.sort) return 1;
return 0;
});
}
return (
<ul>
{
menus.map((item, index) => {
if (item.isEmpty) {
return null;
}
if (item.children && item.children.length < 1) return null;
if (item.props && item.props.visible === true) return null;
if (/^README(.*)md$/.test(item.name)) return null;
return (
<li key={index}>
<div className={classNames({ active: pathname === item.routePath })}>
{item && item.props && (item.props.redirect || item.props.isEmpty) ? <div>{(item.mdconf && item.mdconf.title) || ''}</div> : (
<Link to={item.routePath} replace={pathname === item.routePath}>
{item && item.mdconf.title ? item.mdconf.title : item.name}
</Link>
)}
</div>
{item.children && item.children.length > 0 && this.renderSubMenuItem(item.children)}
</li>
);
})
}
</ul>
);
}
renderSubMenu(menus) {
const { location: { pathname }, routeData } = this.props;
const article = getCurrentArticle(routeData, pathname);
menus = menus.filter(item => item.article === article);
if (menus.length < 1) return null;
const menusObject = menus[0] && menus[0].children ? menus[0].children : [];
return this.renderSubMenuItem(menusObject);
}
isCurentChildren() {
const { location: { pathname }, menuSource, routeData } = this.props;
const getRoute = routeData.filter(item => pathname === item.path);
const article = getRoute.length > 0 ? getRoute[0].article : null;
const childs = menuSource.filter(item => article === item.article && item.children && item.children.length > 1);
return childs.length > 0;
}
render() {
const { menuSource, routeData, indexProps } = this.props;
const isChild = this.isCurentChildren();
return (
<div className={styles.wapper} >
<Header logo={logo} href="/" location={this.props.location} indexProps={indexProps} menuSource={menuSource} />
<div className={styles.wapperContent}>
{isChild && (
<div className={styles.menuWapper}> {this.renderSubMenu(menuSource)} </div>
)}
<div className={classNames('content', {
[`${styles.content}`]: isChild,
[`${styles.contentNoMenu}`]: !isChild,
})}
>
<Switch>
{routeData.map((item) => {
// 重定向跳转
if (item && item.mdconf && item.mdconf.redirect) {
let redirectPath = `${item.path || ''}/${item.mdconf.redirect}`;
redirectPath = redirectPath.replace(/^\/\//, '/');
return (
<Route key={item.path} exact path={item.path} render={() => <Redirect to={redirectPath} />} />
);
}
return (
<Route key={item.path}
exact
path={item.path}
render={() => {
const Comp = item.component;
return <Comp {...item} />;
}}
/>
);
})}
<Redirect to="/404" />
</Switch>
</div>
<Footer />
</div>
</div>
);
}
}