Commit 31af67c2 authored by WhatAKitty's avatar WhatAKitty Committed by 偏右

Fix dynamic component remount #114 #150 (#184)

parent debfa508
import dynamic from 'dva/dynamic';
const data = [{
component: app => dynamic({
export const getNavData = app => [{
component: dynamic({
app,
models: () => [
import('../models/user'),
......@@ -18,7 +18,7 @@ const data = [{
children: [{
name: '分析页',
path: 'analysis',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/chart'),
......@@ -28,7 +28,7 @@ const data = [{
}, {
name: '监控页',
path: 'monitor',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/monitor'),
......@@ -38,7 +38,7 @@ const data = [{
}, {
name: '工作台',
path: 'workplace',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/project'),
......@@ -55,7 +55,7 @@ const data = [{
children: [{
name: '基础表单',
path: 'basic-form',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/form'),
......@@ -65,7 +65,7 @@ const data = [{
}, {
name: '分步表单',
path: 'step-form',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/form'),
......@@ -74,7 +74,7 @@ const data = [{
}),
children: [{
path: 'confirm',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/form'),
......@@ -83,7 +83,7 @@ const data = [{
}),
}, {
path: 'result',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/form'),
......@@ -94,7 +94,7 @@ const data = [{
}, {
name: '高级表单',
path: 'advanced-form',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/form'),
......@@ -109,7 +109,7 @@ const data = [{
children: [{
name: '查询表格',
path: 'table-list',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/rule'),
......@@ -119,7 +119,7 @@ const data = [{
}, {
name: '标准列表',
path: 'basic-list',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/list'),
......@@ -129,7 +129,7 @@ const data = [{
}, {
name: '卡片列表',
path: 'card-list',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/list'),
......@@ -139,7 +139,7 @@ const data = [{
}, {
name: '搜索列表(项目)',
path: 'cover-card-list',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/list'),
......@@ -149,7 +149,7 @@ const data = [{
}, {
name: '搜索列表(应用)',
path: 'filter-card-list',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/list'),
......@@ -159,7 +159,7 @@ const data = [{
}, {
name: '搜索列表(文章)',
path: 'search',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/list'),
......@@ -174,7 +174,7 @@ const data = [{
children: [{
name: '基础详情页',
path: 'basic',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/profile'),
......@@ -184,7 +184,7 @@ const data = [{
}, {
name: '高级详情页',
path: 'advanced',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/profile'),
......@@ -199,14 +199,14 @@ const data = [{
children: [{
name: '成功',
path: 'success',
component: app => dynamic({
component: dynamic({
app,
component: () => import('../routes/Result/Success'),
}),
}, {
name: '失败',
path: 'fail',
component: app => dynamic({
component: dynamic({
app,
component: () => import('../routes/Result/Error'),
}),
......@@ -218,28 +218,28 @@ const data = [{
children: [{
name: '403',
path: '403',
component: app => dynamic({
component: dynamic({
app,
component: () => import('../routes/Exception/403'),
}),
}, {
name: '404',
path: '404',
component: app => dynamic({
component: dynamic({
app,
component: () => import('../routes/Exception/404'),
}),
}, {
name: '500',
path: '500',
component: app => dynamic({
component: dynamic({
app,
component: () => import('../routes/Exception/500'),
}),
}],
}],
}, {
component: app => dynamic({
component: dynamic({
app,
component: () => import('../layouts/UserLayout'),
}),
......@@ -252,7 +252,7 @@ const data = [{
children: [{
name: '登录',
path: 'login',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/login'),
......@@ -262,7 +262,7 @@ const data = [{
}, {
name: '注册',
path: 'register',
component: app => dynamic({
component: dynamic({
app,
models: () => [
import('../models/register'),
......@@ -272,14 +272,14 @@ const data = [{
}, {
name: '注册结果',
path: 'register-result',
component: app => dynamic({
component: dynamic({
app,
component: () => import('../routes/User/RegisterResult'),
}),
}],
}],
}, {
component: app => dynamic({
component: dynamic({
app,
component: () => import('../layouts/BlankLayout'),
}),
......@@ -291,9 +291,3 @@ const data = [{
icon: 'book',
},
}];
export function getNavData() {
return data;
}
export default data;
......@@ -11,8 +11,6 @@ import classNames from 'classnames';
import HeaderSearch from '../components/HeaderSearch';
import NoticeIcon from '../components/NoticeIcon';
import GlobalFooter from '../components/GlobalFooter';
import { getNavData } from '../common/nav';
import { getRouteData } from '../utils/utils';
import NotFound from '../routes/Exception/404';
import styles from './BasicLayout.less';
......@@ -48,15 +46,15 @@ class BasicLayout extends React.PureComponent {
constructor(props) {
super(props);
// 把一级 Layout 的 children 作为菜单项
this.menus = getNavData().reduce((arr, current) => arr.concat(current.children), []);
this.menus = props.navData.reduce((arr, current) => arr.concat(current.children), []);
this.state = {
openKeys: this.getDefaultCollapsedSubMenus(props),
};
}
getChildContext() {
const { location } = this.props;
const { location, navData, getRouteData } = this.props;
const routeData = getRouteData('BasicLayout');
const firstMenuData = getNavData().reduce((arr, current) => arr.concat(current.children), []);
const firstMenuData = navData.reduce((arr, current) => arr.concat(current.children), []);
const menuData = this.getMenuData(firstMenuData, '');
const breadcrumbNameMap = {};
......@@ -166,7 +164,7 @@ class BasicLayout extends React.PureComponent {
});
}
getPageTitle() {
const { location } = this.props;
const { location, getRouteData } = this.props;
const { pathname } = location;
let title = 'Ant Design Pro';
getRouteData('BasicLayout').forEach((item) => {
......@@ -203,15 +201,6 @@ class BasicLayout extends React.PureComponent {
});
return groupBy(newNotices, 'type');
}
getRouteComponent(item) {
if (this.routeComponents[item.path]) {
return this.routeComponents[item.path];
}
const component = item.component(this.props.app);
this.routeComponents[item.path] = component;
return component;
}
routeComponents = {};
handleOpenChange = (openKeys) => {
const lastOpenKey = openKeys[openKeys.length - 1];
const isMainMenu = this.menus.some(
......@@ -248,7 +237,7 @@ class BasicLayout extends React.PureComponent {
}
}
render() {
const { currentUser, collapsed, fetchingNotices } = this.props;
const { currentUser, collapsed, fetchingNotices, getRouteData } = this.props;
const menu = (
<Menu className={styles.menu} selectedKeys={[]} onClick={this.onMenuClick}>
......@@ -361,7 +350,7 @@ class BasicLayout extends React.PureComponent {
exact={item.exact}
key={item.path}
path={item.path}
component={this.getRouteComponent(item)}
component={item.component}
/>
)
)
......
......@@ -5,7 +5,6 @@ import DocumentTitle from 'react-document-title';
import { Icon } from 'antd';
import GlobalFooter from '../components/GlobalFooter';
import styles from './UserLayout.less';
import { getRouteData } from '../utils/utils';
const links = [{
title: '帮助',
......@@ -29,7 +28,7 @@ class UserLayout extends React.PureComponent {
return { location };
}
getPageTitle() {
const { location } = this.props;
const { getRouteData, location } = this.props;
const { pathname } = location;
let title = 'Ant Design Pro';
getRouteData('UserLayout').forEach((item) => {
......@@ -39,16 +38,9 @@ class UserLayout extends React.PureComponent {
});
return title;
}
getRouteComponent(item) {
if (this.routeComponents[item.path]) {
return this.routeComponents[item.path];
}
const component = item.component(this.props.app);
this.routeComponents[item.path] = component;
return component;
}
routeComponents = {};
render() {
const { getRouteData } = this.props;
return (
<DocumentTitle title={this.getPageTitle()}>
<div className={styles.container}>
......@@ -68,7 +60,7 @@ class UserLayout extends React.PureComponent {
exact={item.exact}
key={item.path}
path={item.path}
component={this.getRouteComponent()}
component={item.component}
/>
)
)
......
......@@ -3,31 +3,59 @@ import { Router, Route, Switch } from 'dva/router';
import { LocaleProvider, Spin } from 'antd';
import zhCN from 'antd/lib/locale-provider/zh_CN';
import dynamic from 'dva/dynamic';
import cloneDeep from 'lodash/cloneDeep';
import { getNavData } from './common/nav';
import { getPlainNode } from './utils/utils';
import styles from './index.less';
dynamic.setDefaultLoadingComponent(() => {
return <Spin size="large" className={styles.globalSpin} />;
});
function getRouteData(navData, path) {
if (!navData.some(item => item.layout === path) ||
!(navData.filter(item => item.layout === path)[0].children)) {
return null;
}
const route = cloneDeep(navData.filter(item => item.layout === path)[0]);
const nodeList = getPlainNode(route.children);
return nodeList;
}
function getLayout(navData, path) {
if (!navData.some(item => item.layout === path) ||
!(navData.filter(item => item.layout === path)[0].children)) {
return null;
}
const route = navData.filter(item => item.layout === path)[0];
return {
component: route.component,
layout: route.layout,
name: route.name,
path: route.path,
};
}
function RouterConfig({ history, app }) {
const BasicLayout = dynamic({
app,
models: () => [
import('./models/user'),
],
component: () => import('./layouts/BasicLayout'),
});
const UserLayout = dynamic({
const navData = getNavData(app);
const UserLayout = getLayout(navData, 'UserLayout').component;
const BasicLayout = getLayout(navData, 'BasicLayout').component;
const passProps = {
app,
component: () => import('./layouts/UserLayout'),
});
navData,
getRouteData: (path) => {
return getRouteData(navData, path);
},
};
return (
<LocaleProvider locale={zhCN}>
<Router history={history}>
<Switch>
<Route path="/user" render={props => <UserLayout {...props} app={app} />} />
<Route path="/" render={props => <BasicLayout {...props} app={app} />} />
<Route path="/user" render={props => <UserLayout {...props} {...passProps} />} />
<Route path="/" render={props => <BasicLayout {...props} {...passProps} />} />
</Switch>
</Router>
</LocaleProvider>
......
import moment from 'moment';
import cloneDeep from 'lodash/cloneDeep';
import navData from '../common/nav';
export function fixedZero(val) {
return val * 1 < 10 ? `0${val}` : val;
......@@ -52,7 +49,7 @@ export function getTimeDistance(type) {
}
}
function getPlainNode(nodeList, parentPath = '') {
export function getPlainNode(nodeList, parentPath = '') {
const arr = [];
nodeList.forEach((node) => {
const item = node;
......@@ -70,16 +67,6 @@ function getPlainNode(nodeList, parentPath = '') {
return arr;
}
export function getRouteData(path) {
if (!navData.some(item => item.layout === path) ||
!(navData.filter(item => item.layout === path)[0].children)) {
return null;
}
const dataList = cloneDeep(navData.filter(item => item.layout === path)[0]);
const nodeList = getPlainNode(dataList.children);
return nodeList;
}
export function digitUppercase(n) {
const fraction = ['', ''];
const digit = ['', '', '', '', '', '', '', '', '', ''];
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment