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 ? [