From f4dc3d1285f13eedeb3c5379b395da755a99959e Mon Sep 17 00:00:00 2001
From: X-neuron <398570508@qq.com>
Date: Sat, 11 Dec 2021 20:59:00 +0800
Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81react-router6,ahook3,?=
=?UTF-8?q?=E4=BF=AE=E5=A4=8D#19=E8=8F=9C=E5=8D=95=E6=89=93=E5=BC=80?=
=?UTF-8?q?=E5=A4=B1=E8=B4=A5=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E6=9B=B4?=
=?UTF-8?q?=E6=96=B0=E4=BE=9D=E8=B5=96=E8=87=B3=E6=9C=80=E6=96=B0=EF=BC=8C?=
=?UTF-8?q?=E7=A7=BB=E9=99=A4=E4=B8=8D=E5=BF=85=E8=A6=81=E7=9A=84=E5=8C=85?=
=?UTF-8?q?=EF=BC=8C=E5=88=A0=E9=99=A4=E5=A4=9A=E4=BD=99webpack=E9=85=8D?=
=?UTF-8?q?=E7=BD=AE=E9=A1=B9=EF=BC=8C=E4=BC=98=E5=8C=96=E5=9B=BD=E9=99=85?=
=?UTF-8?q?=E5=8C=96=E5=8A=A0=E8=BD=BD=E9=80=BB=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.gitignore | 1 +
package.json | 105 ++++++++++++-----------
src/app.jsx | 11 ++-
src/atoms/locale.js | 79 ++++++++++-------
src/atoms/route.js | 18 ++--
src/components/CountDownButton/index.jsx | 6 +-
src/components/Locale/index.jsx | 14 +--
src/components/TabRoute/index.jsx | 6 +-
src/config/routes.js | 13 +--
src/layouts/BasicLayout.jsx | 52 ++++-------
src/pages/user/register/index.jsx | 8 +-
src/utils/route-utils.js | 75 ++++++++++------
webpack/webpack.config.js | 7 --
13 files changed, 209 insertions(+), 186 deletions(-)
diff --git a/.gitignore b/.gitignore
index 6200fd3..cb7d77e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,5 +14,6 @@ run/
*.un~
typings/
.nyc_output/
+.vscode/
database/
diff --git a/package.json b/package.json
index c08f9d6..9b207d3 100644
--- a/package.json
+++ b/package.json
@@ -7,6 +7,7 @@
"build": "npx cross-env NODE_ENV=production webpack --mode=production --config ./webpack/webpack.config.js",
"dev": "npx cross-env NODE_ENV=development webpack serve --mode=development --config ./webpack/webpack.config.js",
"test": "jest",
+ "debug-webpack": "node --inspect-brk=5858 ./node_modules/.bin/webpack --mode=development --config ./webpack/webpack.config.js",
"extract": "lingui extract",
"compile": "lingui compile",
"lint": "npm run lint:js && npm run lint:style && npm run lint:prettier",
@@ -57,7 +58,7 @@
"devDependencies": {
"@babel/cli": "^7.16.0",
"@babel/core": "^7.16.0",
- "@babel/eslint-parser": "^7.16.0",
+ "@babel/eslint-parser": "^7.16.3",
"@babel/eslint-plugin": "^7.14.5",
"@babel/plugin-proposal-class-properties": "^7.16.0",
"@babel/plugin-proposal-export-default-from": "^7.16.0",
@@ -65,119 +66,119 @@
"@babel/plugin-transform-modules-commonjs": "^7.16.0",
"@babel/plugin-transform-react-constant-elements": "^7.16.0",
"@babel/plugin-transform-react-inline-elements": "^7.16.0",
- "@babel/plugin-transform-runtime": "^7.16.0",
- "@babel/preset-env": "^7.16.0",
+ "@babel/plugin-transform-runtime": "^7.16.4",
+ "@babel/preset-env": "^7.16.4",
"@babel/preset-react": "^7.16.0",
- "@lingui/cli": "^3.12.1",
- "@lingui/macro": "^3.12.1",
- "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
+ "@lingui/cli": "^3.13.0",
+ "@lingui/macro": "^3.13.0",
+ "@pmmmwh/react-refresh-webpack-plugin": "^0.5.3",
"@umijs/babel-plugin-auto-css-modules": "^3.5.20",
"babel-loader": "^8.2.3",
"babel-plugin-dynamic-import-node": "^2.3.3",
"babel-plugin-import": "^1.13.3",
"babel-plugin-lodash": "^3.3.4",
"babel-plugin-macros": "^3.1.0",
- "browserslist": "^4.17.6",
+ "browserslist": "^4.18.1",
"case-sensitive-paths-webpack-plugin": "^2.4.0",
"circular-dependency-plugin": "^5.2.2",
- "compression-webpack-plugin": "^9.0.0",
- "copy-webpack-plugin": "^9.0.1",
+ "compression-webpack-plugin": "^9.1.1",
+ "copy-webpack-plugin": "^10.1.0",
"cross-env": "^7.0.3",
"cross-port-killer": "^1.3.0",
"css-loader": "^6.5.1",
- "css-minimizer-webpack-plugin": "^3.1.1",
- "eslint": "^8.2.0",
- "eslint-config-airbnb": "^18.2.1",
- "eslint-config-airbnb-base": "^14.2.1",
+ "css-minimizer-webpack-plugin": "^3.2.0",
+ "eslint": "^8.4.1",
+ "eslint-config-airbnb": "^19.0.2",
+ "eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.3.0",
"eslint-config-react-app": "^6.0.0",
"eslint-friendly-formatter": "^4.0.1",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-import-resolver-webpack": "^0.13.2",
- "eslint-plugin-compat": "^3.13.0",
+ "eslint-plugin-compat": "^4.0.0",
"eslint-plugin-html": "^6.2.0",
- "eslint-plugin-import": "^2.25.2",
- "eslint-plugin-jest": "^25.2.4",
- "eslint-plugin-jsx-a11y": "^6.4.1",
+ "eslint-plugin-import": "^2.25.3",
+ "eslint-plugin-jest": "^25.3.0",
+ "eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-markdown": "^2.2.1",
"eslint-plugin-prettier": "^4.0.0",
- "eslint-plugin-promise": "^5.1.1",
- "eslint-plugin-react": "^7.26.1",
- "eslint-plugin-react-hooks": "^4.2.0",
- "eslint-webpack-plugin": "^3.1.0",
+ "eslint-plugin-promise": "^5.2.0",
+ "eslint-plugin-react": "^7.27.1",
+ "eslint-plugin-react-hooks": "^4.3.0",
+ "eslint-webpack-plugin": "^3.1.1",
"file-loader": "^6.2.0",
"html-loader": "^3.0.1",
"html-webpack-plugin": "^5.5.0",
"husky": "^7.0.4",
- "jest": "^27.3.1",
+ "jest": "^27.4.4",
"less": "^4.1.2",
"less-loader": "^10.2.0",
- "lint-staged": "^11.2.6",
- "mini-css-extract-plugin": "^2.4.4",
+ "lint-staged": "^12.1.2",
+ "mini-css-extract-plugin": "^2.4.5",
"mockjs": "^1.1.0",
- "node-sass": "^6.0.1",
+ "node-sass": "^7.0.0",
"npm-run-all": "^4.1.5",
"optimize-css-assets-webpack-plugin": "^6.0.1",
"pnp-webpack-plugin": "^1.7.0",
- "postcss": "^8.3.11",
+ "postcss": "^8.4.4",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-import": "^14.0.2",
- "postcss-loader": "^6.2.0",
+ "postcss-loader": "^6.2.1",
"postcss-normalize": "^10.0.1",
- "postcss-preset-env": "^6.7.0",
+ "postcss-preset-env": "^7.0.1",
"postcss-safe-parser": "^6.0.0",
- "prettier": "^2.4.1",
+ "prettier": "^2.5.1",
"raw-loader": "^4.0.2",
"react-dev-utils": "^11.0.4",
"react-perf-devtool": "^3.1.8",
- "react-refresh": "^0.10.0",
+ "react-refresh": "^0.11.0",
"resolve-url-loader": "^4.0.0",
- "sass": "^1.43.4",
- "sass-loader": "^12.3.0",
+ "sass": "^1.45.0",
+ "sass-loader": "^12.4.0",
"source-map-loader": "^3.0.0",
"style-loader": "^3.3.1",
- "stylelint": "^14.0.1",
+ "stylelint": "^14.1.0",
"stylelint-config-recommended": "^6.0.0",
"stylelint-config-styled-components": "^0.1.1",
"stylelint-processor-styled-components": "^1.10.0",
"sugarss": "^4.0.1",
- "terser-webpack-plugin": "^5.2.4",
+ "terser-webpack-plugin": "^5.2.5",
"url-loader": "^4.1.1",
- "webpack": "^5.62.1",
+ "webpack": "^5.65.0",
"webpack-bundle-analyzer": "^4.5.0",
"webpack-cli": "^4.9.1",
"webpack-dashboard": "^3.3.6",
- "webpack-dev-server": "4.4.0",
+ "webpack-dev-server": "4.6.0",
"webpack-manifest-plugin": "^4.0.2",
"webpackbar": "^5.0.2",
- "workbox-webpack-plugin": "^6.3.0"
+ "workbox-webpack-plugin": "^6.4.2"
},
"dependencies": {
- "@ahooksjs/use-request": "^2.8.13",
"@ant-design/icons": "^4.7.0",
- "@ant-design/pro-card": "^1.17.0",
- "@ant-design/pro-descriptions": "^1.9.29",
- "@ant-design/pro-field": "^1.24.1",
- "@ant-design/pro-form": "^1.46.0",
- "@ant-design/pro-layout": "^6.27.2",
- "@ant-design/pro-list": "^1.18.0",
- "@ant-design/pro-table": "^2.56.8",
- "@babel/runtime": "^7.16.0",
+ "@ant-design/pro-card": "^1.18.10",
+ "@ant-design/pro-descriptions": "^1.10.15",
+ "@ant-design/pro-field": "^1.28.8",
+ "@ant-design/pro-form": "^1.49.12",
+ "@ant-design/pro-layout": "^6.31.7",
+ "@ant-design/pro-list": "^1.20.15",
+ "@ant-design/pro-table": "^2.59.10",
+ "@babel/runtime": "^7.16.3",
"@koale/useworker": "^4.0.2",
- "@lingui/react": "^3.12.1",
- "ahooks": "^2.10.12",
- "antd": "^4.16.13",
+ "@lingui/detect-locale": "^3.13.0",
+ "@lingui/react": "^3.13.0",
+ "ahooks": "^3.0.1",
+ "antd": "^4.17.3",
"classnames": "^2.3.1",
"history": "^5.1.0",
"lodash": "^4.17.21",
"nano-memoize": "^1.2.1",
"nanoid": "^3.1.30",
- "qiankun": "^2.5.1",
- "qs": "^6.10.1",
+ "qiankun": "^2.6.2",
+ "qs": "^6.10.2",
"react": "^17.0.2",
"react-avatar-editor": "^12.0.0",
"react-dom": "^17.0.2",
- "react-router-dom": "^6.0.1",
+ "react-router-dom": "^6.1.0",
"react-use": "^17.3.1",
"recoil": "^0.5.2",
"umi-request": "^1.4.0"
diff --git a/src/app.jsx b/src/app.jsx
index 4a5e632..05a0fdb 100644
--- a/src/app.jsx
+++ b/src/app.jsx
@@ -1,4 +1,5 @@
-
+import { Suspense } from "react";
+import PageLoading from "@/components/PageLoading";
import { useRoutes } from "react-router-dom";
// import { setConfig } from 'react-hot-loader';
import Locale from "@/components/Locale";
@@ -20,9 +21,11 @@ function App() {
let element = useRoutes(appRoute);
return (
-
- {element}
-
+ } >
+
+ {element}
+
+
)
}
diff --git a/src/atoms/locale.js b/src/atoms/locale.js
index 729b1d4..52b1cc7 100644
--- a/src/atoms/locale.js
+++ b/src/atoms/locale.js
@@ -2,6 +2,30 @@ import { atom, selector } from "recoil";
import { i18n } from "@lingui/core";
+const localStorageLangEffect = key => ({setSelf, onSet, trigger}) => {
+ // If there's a persisted value - set it on load
+ const loadPersisted = async () => {
+ const savedValue = await localStorage.getItem(key);
+
+ if (savedValue != null) {
+ setSelf(JSON.parse(savedValue));
+ }
+ };
+
+ // Asynchronously set the persisted data
+ if (trigger === 'get') {
+ loadPersisted();
+ }
+
+ // Subscribe to state changes and persist them to localStorage
+ onSet((newValue, _, isReset) => {
+ isReset
+ ? localStorage.removeItem(key)
+ : localStorage.setItem(key, JSON.stringify(newValue));
+ });
+};
+
+
export const locales = {
"zh-CN":{
name:"简体中文",
@@ -27,19 +51,32 @@ export const locales = {
export const curLangAtom = atom({
key: "curLangAtom",
default: "zh-CN",
- effects_UNSTABLE:[
- ({onSet}) => {
- // 用户国际化内容,同时菜单也国际化
- onSet((newLang,oldValue) => {
- if(newLang !== oldValue) {
- dynamicActivateCustomLocale(newLang)
+ // effects_UNSTABLE:[
+ // ({onSet}) => {
+ // // 用户国际化内容,同时菜单也国际化
+ // onSet((newLang,oldValue) => {
+ // if(newLang !== oldValue) {
+ // dynamicActivateCustomLocale(newLang)
- }
- })
- }
- ]
+ // }
+ // })
+ // },
+ // localStorageLangEffect('lang')
+ // ]
});
+export const curLocaleLoadAtom = selector({
+ key:"curLocaleLoadAtom",
+ default:'none',
+ get:async ({get}) => {
+ const lang = get(curLangAtom);
+ const { messages } = await import(/* webpackChunkName: 'i18n' */`@/locales/${lang}.js`);
+ i18n.load(lang, messages)
+ i18n.activate(lang)
+ return lang;
+ }
+})
+
// UI 国际化内容
// UI 内容随curLangAtom 而改变,故为selector
@@ -50,25 +87,3 @@ export const antdLocaleAtom = selector({
return locales[get(curLangAtom)].antd
}
});
-
-
-/**
-* We do a dynamic import of just the catalog that we need
-* @param locale any locale string
-*/
- async function dynamicActivateCustomLocale(locale) {
-
- // request.get(`${window.location.origin}/public/locales/${locale}.json`,{
- // // request.get(`./public/locales/${locale}.json`,{
- // responseType: "json",
- // }).then(
- // res => {
- // i18n.load(locale, res)
- // i18n.activate(locale)
- // }
- // )
-
- const { messages } = await import(/* webpackChunkName: 'i18n' */`@/locales/${locale}.js`);
- i18n.load(locale, messages)
- i18n.activate(locale)
-}
diff --git a/src/atoms/route.js b/src/atoms/route.js
index 8c7ebd7..5a4534d 100644
--- a/src/atoms/route.js
+++ b/src/atoms/route.js
@@ -1,6 +1,6 @@
import { atom,selector } from 'recoil';
-import {staticConfig,dynamicConfig,generateRouteAndProlayoutMenus,mergeRoute} from '@/utils/route-utils';
-import { curLangAtom } from '@/atoms/locale';
+import {staticConfig,dynamicConfig,generateRouteAndProlayoutMenus,mergeRoute,translateNameProperty} from '@/utils/route-utils';
+import { curLocaleLoadAtom } from '@/atoms/locale';
// import { i18n } from "@lingui/core";
// import memoized from "nano-memoize";
@@ -24,7 +24,7 @@ import { curLangAtom } from '@/atoms/locale';
// export const transDynamicConfigAtom = selector({
// key:'transDynamicConfigAtom',
// get:({get}) => {
- // return transConfigName(get(dynamicConfigAtom),get(curLangAtom));
+ // return transConfigName(get(dynamicConfigAtom),get(curLocaleLoadAtom));
// }
// });
@@ -51,12 +51,12 @@ import { curLangAtom } from '@/atoms/locale';
},
});
// 翻译name,方便后续使用
- // export const transDynamicRouteAtom = selector({
- // key: 'transDynamicRouteAtom',
- // get:({get}) => {
- // return translateNameProperty(get(dynamicRouteAtom),get(curLangAtom));
- // }
- // });
+ export const transDynamicRouteAtom = selector({
+ key: 'transDynamicRouteAtom',
+ get:async ({get}) => {
+ return translateNameProperty(get(dynamicRouteAtom),get(curLocaleLoadAtom));
+ }
+ });
export const appRouteAtom = selector({
key:'appRouteAtom',
diff --git a/src/components/CountDownButton/index.jsx b/src/components/CountDownButton/index.jsx
index a6f54e7..13ff5e5 100644
--- a/src/components/CountDownButton/index.jsx
+++ b/src/components/CountDownButton/index.jsx
@@ -1,8 +1,8 @@
import { Button } from "antd";
// import { useInterval, useBoolean } from "react-use";
-// import { usePersistFn, useCounter } from "ahooks"
-import { usePersistFn, useInterval, useBoolean, useCounter,useSafeState } from "ahooks"
+// import { useMemoizedFn, useCounter } from "ahooks"
+import { useMemoizedFn, useInterval, useBoolean, useCounter,useSafeState } from "ahooks"
/* 是否开始倒计时
start?: boolean;
@@ -31,7 +31,7 @@ const CountDownButton = ({ start, second, initText, resetText, runText, onEnd, .
const [delay] = useSafeState(1000); // 1000
const [done, doneOp] = useBoolean(false);
- const timeout = usePersistFn(() => {
+ const timeout = useMemoizedFn(() => {
// 设置为运行结束后状态
// 发出倒计时结束事件
onEnd && onEnd();
diff --git a/src/components/Locale/index.jsx b/src/components/Locale/index.jsx
index 2e0118d..3aa2f2d 100644
--- a/src/components/Locale/index.jsx
+++ b/src/components/Locale/index.jsx
@@ -1,33 +1,33 @@
-import { Suspense } from "react";
+// import { Suspense } from "react";
import { i18n } from "@lingui/core"
import { I18nProvider } from "@lingui/react"
-import PageLoading from "@/components/PageLoading";
+// import PageLoading from "@/components/PageLoading";
import { useMount } from "ahooks";
import { ConfigProvider } from "antd";
-import { curLangAtom,antdLocaleAtom } from "@/atoms";
+import {antdLocaleAtom,curLocaleLoadAtom,curLangAtom } from "@/atoms/locale";
import { useRecoilValue } from "recoil";
// import zh from "@/locales/zh-CN"; // 默认加载中文。 lingui-detect尚不稳定
+
const Locale = ({ children }) => {
- const lang = useRecoilValue(curLangAtom);
+ const defaultLang = useRecoilValue(curLocaleLoadAtom);
+ const lang = useRecoilValue(curLocaleLoadAtom);
const antdLocale = useRecoilValue(antdLocaleAtom);
useMount(async () => {
- const { messages } = await import(/* webpackChunkName: 'i18n' */`@/locales/zh-CN.js`);
+ const { messages } = await import(/* webpackChunkName: 'i18n' */`@/locales/${defaultLang}.js`);
i18n.load(lang, messages)
i18n.activate(lang)
})
return (
- } >
{children}
-
)
}
diff --git a/src/components/TabRoute/index.jsx b/src/components/TabRoute/index.jsx
index c06c989..3ce012a 100644
--- a/src/components/TabRoute/index.jsx
+++ b/src/components/TabRoute/index.jsx
@@ -4,7 +4,7 @@ import PageLoading from "@/components/PageLoading";
// import Lru from "@/utils/lru";
import memoized from "nano-memoize";
import _ from 'lodash';
-import { usePersistFn, useCreation } from "ahooks";
+import { useMemoizedFn, useCreation } from "ahooks";
// import { useWhyDidYouUpdate } from 'ahooks';
import { useOutlet,useNavigate,useLocation,generatePath,useParams } from "react-router-dom";
@@ -87,7 +87,7 @@ const TabRoute = (props) => {
},[location]);
- const closeTab = usePersistFn((selectKey) => {
+ const closeTab = useMemoizedFn((selectKey) => {
// 记录原真实路由,微前端可能修改
// keyLruSquence.newest.value.curPath = window.location.pathname
// navigate(keyLruSquence.get(selectKey).curPath,{replace:true});
@@ -99,7 +99,7 @@ const TabRoute = (props) => {
});
- const selectTab = usePersistFn((selectKey) => {
+ const selectTab = useMemoizedFn((selectKey) => {
// 记录原真实路由,微前端可能修改
navigate(getTabPath(tabList.current.get(getTabMapKey(selectKey))),{replace:true});
});
diff --git a/src/config/routes.js b/src/config/routes.js
index a3e770e..566dee1 100644
--- a/src/config/routes.js
+++ b/src/config/routes.js
@@ -5,13 +5,14 @@
// component 无 page 说明只是个路径,无需对应组件
// function routeConfig() {
// 纯json的配置,主要为了在无框架条件下 实现 json 路由配置的动态修改
+// react-router6 支持index route 和 prolayout route ,caseSensitive 配置 与 Muti app 的 basePath 写法。
const routes = [
{
- path:'/',
+ // path:'/',
component:'blankLayout',
children:[
{
- path: "user",
+ path: "/user",
component:'userLayout',
children: [
{
@@ -25,17 +26,19 @@
]
},
{
- path: '/',
+ // path: '/', // prolayout route写法
component: 'securityLayout',
children:[
{
- path: "/",
+ // path: "/", // prolayout route写法
component: "basicLayout",
// access:'validUser',
// 之所以用menuTabs 为了将功能单独做成动态的route
menuTabs: [
{
- path: "/",
+ // path: "/",
+ path:"/",
+ index:true, // index route写法
name: "欢迎菜单", // 翻译失败后 则采用name配置值,如无需全球化直接使用中文即可。
icon: "HomeOutlined", // @/config/icons里配置的图标,小写也可以
access: "dashboardOpen", // @/config/access里可配置静态策略。权限入口在@/config/pages里。
diff --git a/src/layouts/BasicLayout.jsx b/src/layouts/BasicLayout.jsx
index 89c6979..6392a9c 100644
--- a/src/layouts/BasicLayout.jsx
+++ b/src/layouts/BasicLayout.jsx
@@ -14,9 +14,9 @@ import TabRoute from '@/components/TabRoute';
import logo from '@/assets/logo.svg';
import styles from './BasicLayout.less';
-import { useCreation } from 'ahooks';
-import { curLangAtom } from '@/atoms/locale';
-import { dynamicRouteAtom } from '@/atoms/route';
+import { useCreation,useLatest } from 'ahooks';
+import { curLocaleLoadAtom } from '@/atoms/locale';
+import { dynamicRouteAtom,transDynamicRouteAtom } from '@/atoms/route';
import { tabsModelAtom } from '@/atoms/tabsModel';
import { useRecoilValue, useRecoilState } from 'recoil';
@@ -36,29 +36,6 @@ const pickRoutes = memoized((routes, pathname) => {
};
});
-//因为recoil生成的数据是readonly。所以深拷贝下。
-const translateNameProperty = (route, locale) => {
- let newRoute = [];
- const transObjectName = (curRoute) => {
- let newCurRoute = { ...curRoute };
- if (newCurRoute.name) {
- newCurRoute.name = i18n._(newCurRoute.name);
- }
- if (newCurRoute.children) {
- let newChildren = [];
- newCurRoute.children.forEach((item) => {
- newChildren.push(transObjectName(item));
- });
- newCurRoute.children = newChildren;
- }
- return newCurRoute;
- };
- route.forEach((item) => {
- newRoute.push(transObjectName(item));
- });
-
- return newRoute;
-};
const BasicLayout = (props) => {
const location = useLocation();
@@ -67,22 +44,26 @@ const BasicLayout = (props) => {
fixSiderbar: true,
fixedHeader: true
});
- const locale = useRecoilValue(curLangAtom);
+ const locale = useRecoilValue(curLocaleLoadAtom);
const tabsModel = useRecoilValue(tabsModelAtom);
const navigate = useNavigate();
- const orgRoute = useRecoilValue(dynamicRouteAtom);
-
+ // const orgRoute = useRecoilValue(dynamicRouteAtom);
+ const route = useRecoilValue(transDynamicRouteAtom);
//手工转换下
// transDynamicConfigAtom 貌似无法触发prolayout 的menu 更新,深表痛心。
- const route = useCreation(
- () => translateNameProperty(orgRoute, locale),
- [orgRoute, locale],
- );
+ // const route = useCreation(
+ // () => translateNameProperty(orgRoute, locale),
+ // [orgRoute, locale],
+ // );
+ // 之所以要喂给单独深拷贝喂,因为 https://github.com/umijs/route-utils/pull/10 它好像挺倔,这么反人类的 底裤操作,居然不纠正...
+ const feedToProlayoutRoute = useCreation(() => _.cloneDeep(route),[locale]);
+ console.log(route);
const { routeConfig, matchPath } = pickRoutes(route, location.pathname);
- console.log('selectkey:', matchPath);
+
+ // console.log('selectkey:', matchPath);
// use activeKey ouble render
// const [activeKey,setActiveKey] = useRecoilState(activeKeyAtom);
@@ -92,7 +73,7 @@ const BasicLayout = (props) => {
style={{
height: '100vh',
}}
- menuDataRender={() => route}
+ menuDataRender={() => feedToProlayoutRoute}
menuItemRender={(item, dom) => (
{
@@ -132,7 +113,6 @@ const BasicLayout = (props) => {
{/*
*/}
{tabsModel ? (
diff --git a/src/pages/user/register/index.jsx b/src/pages/user/register/index.jsx
index fd9172d..291df8e 100644
--- a/src/pages/user/register/index.jsx
+++ b/src/pages/user/register/index.jsx
@@ -11,7 +11,7 @@ import { Popover, Progress,Tabs,Space,Form } from "antd";
import ProForm, {ProFormCaptcha, ProFormCheckbox, ProFormText,ProFormSelect,ProFormGroup } from '@ant-design/pro-form';
import Field from '@ant-design/pro-field';
-import { usePersistFn,useSafeState } from "ahooks";
+import { useMemoizedFn,useSafeState } from "ahooks";
import styles from "./index.less";
import { Link } from 'react-router-dom';
@@ -56,7 +56,7 @@ const Register = (props) => {
};
- const checkPwdConfirm = usePersistFn((rule, value, callback) => {
+ const checkPwdConfirm = useMemoizedFn((rule, value, callback) => {
if (value && value !== formRef.current.getFieldValue("password")) {
callback("两次输入的密码不匹配!");
} else {
@@ -97,7 +97,7 @@ const Register = (props) => {
- const getPasswordStatus = usePersistFn(() => {
+ const getPasswordStatus = useMemoizedFn(() => {
const value = formRef.current?.getFieldValue("password");
if (value && value.length > 9) {
return "ok";
@@ -108,7 +108,7 @@ const Register = (props) => {
return "poor";
});
- const renderPasswordProgress = usePersistFn(() => {
+ const renderPasswordProgress = useMemoizedFn(() => {
if(!state.visible){
return (<>>)
}
diff --git a/src/utils/route-utils.js b/src/utils/route-utils.js
index 39eba56..a62119c 100644
--- a/src/utils/route-utils.js
+++ b/src/utils/route-utils.js
@@ -4,11 +4,14 @@ import { resolvePath } from "react-router-dom";
import getPage from "@/config/pages";
import getIcon from '@/config/icons';
import _ from 'lodash';
-// import { i18n } from "@lingui/core";
+import { i18n } from "@lingui/core";
// import { t } from "@lingui/macro";
// 单独 拉出config 因为 修改route的时候,是按"@/config/routes"的格式提供的。
-// 而后端不可能可能提供key,resolvepath之类的参数。
+// 而后端不可能提供key,resolvepath之类的参数。
// staticConfig 以 menutabs 为标志。
+
+const normalizePathname = (pathname) => pathname.replace(/\/+$/, "").replace(/^\/*/, "/");
+
const extractConfig = extractRouteConfig(routeConfig);
export const staticConfig = extractConfig.staticConfig;
export const dynamicConfig = extractConfig.dynamicConfig;
@@ -85,34 +88,44 @@ function extractRouteConfig(rConfig) {
// },
// ]
-// export function transConfigName(routeConfig,locale){
-
-// return routeConfig.map(conf => {
-// let confItem = {
-// ...conf
-// }
-// if(conf.name){
-// confItem.name = i18n._(conf.name);
-// }
-// if(conf.children){
-// confItem.children = transConfigName(conf.children)
-// }
-// return confItem;
-// })
-// }
+// 翻译下route的Name
+export function translateNameProperty (route, locale) {
+ let newRoute = [];
+ const transObjectName = (curRoute) => {
+ let newCurRoute = { ...curRoute };
+ if (newCurRoute.name) {
+ newCurRoute.name = i18n._(newCurRoute.name);
+ }
+ if (newCurRoute.children) {
+ let newChildren = [];
+ newCurRoute.children.forEach((item) => {
+ newChildren.push(transObjectName(item));
+ });
+ newCurRoute.children = newChildren;
+ }
+ return newCurRoute;
+ };
+ route.forEach((item) => {
+ newRoute.push(transObjectName(item));
+ });
+
+ return newRoute;
+};
function generateProlayoutMenuDataItem (menuTabs,basePath) {
return menuTabs.map(conf => {
// fullPath 可去掉*号,以免引起url路径错误
// /*的配置只会在路由 路径的末尾...
- const resPath = resolvePath(_.replace(conf.path,'/*',''),basePath);
+ const resPath = resolvePath(conf.path ? _.replace(conf.path,'/*',''):'/*',normalizePathname(basePath));
let menuDataItem = {
// name为空则component 代替
// 加上翻译
name: conf.name ? conf.name: conf.component,
- // react router6 支持的父子路径
- path: conf.path,
+ // 支持大小写敏感
+ caseSensitive:conf.caseSensitive,
+ // 支持index route
+ index:conf.index,
// 完整路径 parentPath:/a childrenPath:b fullPath:/a/b
fullPath: resPath.pathname,
key:resPath.pathname,
@@ -121,7 +134,10 @@ function generateProlayoutMenuDataItem (menuTabs,basePath) {
caseSensitive: false,
access: conf.access,
}
-
+ // 支持prolayout路由
+ if(conf.path){
+ menuDataItem.path = conf.path
+ }
if (conf.children) {
menuDataItem.children = generateProlayoutMenuDataItem(conf.children,resPath.pathname);
@@ -154,19 +170,25 @@ export function generateRouteAndProlayoutMenus(staticConf,dynamicConf) {
// hideInMenu 会把这个路由配置在 menu 中隐藏这个路由,name 不填会有相同的效果
// hideChildrenInMenu 会把这个路由的子节点在 menu 中隐藏
+
const generateRmtConfig = (config, basePath) => {
return config.map(conf => {
// fullPath 可去掉*号,以免引起url路径错误
- const resPath = resolvePath(_.replace(conf.path,'/*',''),basePath);
+
+ // const resPath = resolvePath(_.replace(conf.path,'/*',''),normalizePathname(basePath));
+ const resPath = resolvePath(conf.path ? _.replace(conf.path,'/*',''):'/*',normalizePathname(basePath));
+ console.log(resPath);
let route = {
value: conf.component,
- // path: curPath,
//reactRouter 6 的 父子path 用来喂给react router6吃的
- path: conf.path,
// 完整路径 parentPath:/a childrenPath:b fullPath:/a/b
// fullPath 可去掉*号,以免引起url路径错误
+ // 支持大小写敏感
+ caseSensitive:conf.caseSensitive,
+ // 支持index route
+ index:conf.index,
fullPath: resPath.pathname,
// element: conf.component,
element: conf.component ? getPage(conf.component,conf.access,resPath.pathname) : getPage("Default"),
@@ -175,6 +197,11 @@ export function generateRouteAndProlayoutMenus(staticConf,dynamicConf) {
name: conf.name ? conf.name: conf.component,
access: conf.access,
}
+ // 支持prolayout路由
+ if(conf.path){
+ route.path = conf.path
+ }
+
if (conf.children) {
route.children = generateRmtConfig(conf.children,resPath.pathname);
}else{
diff --git a/webpack/webpack.config.js b/webpack/webpack.config.js
index 1f5529c..8421246 100644
--- a/webpack/webpack.config.js
+++ b/webpack/webpack.config.js
@@ -207,13 +207,6 @@ module.exports = function () {
// },
// name: `${ process.env.NODE_ENV || 'development'}-cache`
},
- entry: [
- // "core-js/modules/es6.promise",
- // "core-js/modules/es6.array.iterator",
- // path.join(process.cwd(), EntryJS),
- paths.appIndexJs,
- ],
-
entry:
isEnvDevelopment && !shouldUseReactRefresh
? [