From 31af67c2d08747f4ce3bcac42c5811243e657118 Mon Sep 17 00:00:00 2001 From: WhatAKitty <104xuqiang@163.com> Date: Wed, 15 Nov 2017 10:49:58 +0800 Subject: [PATCH] Fix dynamic component remount #114 #150 (#184) --- src/common/nav.js | 62 +++++++++++++++++--------------------- src/layouts/BasicLayout.js | 23 ++++---------- src/layouts/UserLayout.js | 16 +++------- src/router.js | 52 ++++++++++++++++++++++++-------- src/utils/utils.js | 15 +-------- 5 files changed, 79 insertions(+), 89 deletions(-) diff --git a/src/common/nav.js b/src/common/nav.js index e073b479..5446c6b9 100644 --- a/src/common/nav.js +++ b/src/common/nav.js @@ -1,7 +1,7 @@ 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; diff --git a/src/layouts/BasicLayout.js b/src/layouts/BasicLayout.js index 307a15b6..9072852b 100644 --- a/src/layouts/BasicLayout.js +++ b/src/layouts/BasicLayout.js @@ -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 = ( @@ -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} /> ) ) diff --git a/src/layouts/UserLayout.js b/src/layouts/UserLayout.js index 0eb56005..7f9ca2c9 100644 --- a/src/layouts/UserLayout.js +++ b/src/layouts/UserLayout.js @@ -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 (
@@ -68,7 +60,7 @@ class UserLayout extends React.PureComponent { exact={item.exact} key={item.path} path={item.path} - component={this.getRouteComponent()} + component={item.component} /> ) ) diff --git a/src/router.js b/src/router.js index c82ce711..1c9ac52d 100644 --- a/src/router.js +++ b/src/router.js @@ -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 ; }); +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 ( - } /> - } /> + } /> + } /> diff --git a/src/utils/utils.js b/src/utils/utils.js index 297927ef..e0dfd715 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -1,7 +1,4 @@ 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 = ['零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖']; -- GitLab