Compare commits

...

2 Commits
master ... i18n

Author SHA1 Message Date
npmrun d220a7f021 add 2 years ago
npmrun c018d87fbe i18n 4 years ago
  1. 1438
      package-lock.json
  2. 42
      package.json
  3. 1749
      pnpm-lock.yaml
  4. 11
      src/App.tsx
  5. 51
      src/AppRouter.tsx
  6. 10
      src/assets/locales/en-us.json
  7. 10
      src/assets/locales/zh-cn.json
  8. 29
      src/main.tsx
  9. 28
      src/plugins/i18n/index.tsx
  10. 5
      src/route.tsx
  11. 17
      src/ui/Auth.tsx
  12. 6
      src/views/About/index.tsx
  13. 28
      src/views/Login/index.tsx
  14. 4
      vite.config.ts

1438
package-lock.json

File diff suppressed because it is too large

42
package.json

@ -6,27 +6,29 @@
"serve": "vite preview" "serve": "vite preview"
}, },
"dependencies": { "dependencies": {
"axios": "^0.21.1", "axios": "^1.3.4",
"classnames": "^2.3.1", "classnames": "^2.3.2",
"react": "^17.0.0", "i18next": "^22.4.10",
"react-dom": "^17.0.0", "i18next-browser-languagedetector": "^7.0.1",
"react-redux": "^7.2.4", "react": "^18.2.0",
"react-router-dom": "^5.2.0", "react-dom": "^18.2.0",
"redux": "^4.1.0", "react-i18next": "^12.2.0",
"redux-saga": "^1.1.3", "react-redux": "^8.0.5",
"styled-jsx": "^3.4.4" "react-router-dom": "^6.8.2",
"redux": "^4.2.1",
"redux-saga": "^1.2.2",
"styled-jsx": "^5.1.2"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "^15.12.5", "@types/node": "^18.14.5",
"@types/react": "^17.0.0", "@types/react": "^18.0.28",
"@types/react-dom": "^17.0.0", "@types/react-dom": "^18.0.11",
"@types/react-router-dom": "^5.1.7", "@types/react-router-dom": "^5.3.3",
"@vitejs/plugin-react-refresh": "^1.3.1", "@vitejs/plugin-react-swc": "^3.2.0",
"redux-devtools": "^3.7.0", "sass": "^1.58.3",
"sass": "^1.35.1", "typescript": "^4.9.5",
"typescript": "^4.3.2", "vite": "^4.1.4",
"vite": "^2.3.8", "vite-plugin-windicss": "^1.8.10",
"vite-plugin-windicss": "^1.2.0", "windicss": "^3.5.6"
"windicss": "^3.1.3"
} }
} }

1749
pnpm-lock.yaml

File diff suppressed because it is too large

11
src/App.tsx

@ -0,0 +1,11 @@
import React from "react";
export default function App() {
return (
<>
asdsa
</>
)
}

51
src/AppRouter.tsx

@ -1,4 +1,4 @@
import { BrowserRouter as Router, Switch, Redirect, Route, Link } from "react-router-dom" import { BrowserRouter as Router, Routes, Navigate, Route, Link, NavLink } from "react-router-dom"
import React, { Fragment } from "react" import React, { Fragment } from "react"
import { pageList } from "@/plugins/pageHoc" import { pageList } from "@/plugins/pageHoc"
@ -10,7 +10,7 @@ import routes, { Loading } from "./route"
function LoadWrapper(props: any) { function LoadWrapper(props: any) {
if (props.isLazy) { if (props.isLazy) {
const LoadingComp=props.loading?props.loading: ()=><Loading color="#ff0000"></Loading> //NormalLoading; const LoadingComp = props.loading ? props.loading : () => <Loading color="#ff0000"></Loading> //NormalLoading;
return <React.Suspense fallback={<LoadingComp></LoadingComp>}>{props.children}</React.Suspense> return <React.Suspense fallback={<LoadingComp></LoadingComp>}>{props.children}</React.Suspense>
} }
return <Fragment>{props.children}</Fragment> return <Fragment>{props.children}</Fragment>
@ -20,27 +20,44 @@ function RouteMap(props: any) {
const routes: any[] = props.routes const routes: any[] = props.routes
return ( return (
<Switch> <Routes>
{routes.map((route, index) => { {routes.map((route, index) => {
const { exact = false } = route
if (route.redirect) { if (route.redirect) {
return ( return <Route key={index} path={route.path} element={<Navigate to={route.redirect} replace />}></Route>
<Route key={index} path={route.path} exact={exact}>
<Redirect to={route.redirect}></Redirect>
</Route>
)
} }
if (route.component) { if (route.component) {
return ( if (!route.meta?.auth) {
<Auth key={index} needAuth={!!route.meta?.auth} path={route.path} exact={exact}> return (
<LoadWrapper loading={route.loading} isLazy={typeof route.component.$$typeof === "symbol"}> // 如果已经登陆,就直接显示原来的组件
<route.component meta={route.meta}>{route.children && <RouteMap routes={route.children}></RouteMap>}</route.component> <Route
</LoadWrapper> path={route.path}
</Auth> key={index}
) element={
<LoadWrapper loading={route.loading} isLazy={typeof route.component.$$typeof === "symbol"}>
<route.component meta={route.meta}>{route.children && <RouteMap routes={route.children}></RouteMap>}</route.component>
</LoadWrapper>
}
></Route>
)
} else {
return <Route key={index} element={<NavLink to="/login"></NavLink>}></Route>
}
// return (
// <Route
// key={index}
// path={route.path}
// element={
// <Auth key={index} needAuth={!!route.meta?.auth} path={route.path}>
// <LoadWrapper loading={route.loading} isLazy={typeof route.component.$$typeof === "symbol"}>
// <route.component meta={route.meta}>{route.children && <RouteMap routes={route.children}></RouteMap>}</route.component>
// </LoadWrapper>
// </Auth>
// }
// ></Route>
// )
} }
})} })}
</Switch> </Routes>
) )
} }

10
src/assets/locales/en-us.json

@ -0,0 +1,10 @@
{
"login":{
"title": "Bronze Age 2022",
"username_placeholder": "Username",
"password_placeholder": "Password",
"btnText": "Login"
},
"home":"Bronze Age 2021",
"welcome":"Welcome To Home"
}

10
src/assets/locales/zh-cn.json

@ -0,0 +1,10 @@
{
"login":{
"title": "青铜时代2022",
"username_placeholder": "用户名",
"password_placeholder": "密码",
"btnText": "登录"
},
"home":"青铜时代2021",
"welcome":"欢迎来首页"
}

29
src/main.tsx

@ -1,19 +1,20 @@
import "@/assets/style/common.scss"; import "@/assets/style/common.scss"
import store from "@/store"; import store from "@/store"
import React from "react"; import React from "react"
import ReactDOM from "react-dom"; import { createRoot } from "react-dom/client"
import "@/plugins/i18n"
import { Provider } from "react-redux"
import "virtual:windi-devtools"
import "virtual:windi.css"
import {Provider} from 'react-redux' import App from "./App"
import "virtual:windi-devtools";
import "virtual:windi.css";
import Router from "./AppRouter"; const container = document.getElementById("root")
const root = createRoot(container!)
ReactDOM.render( root.render(
<React.StrictMode> <React.StrictMode>
<Provider store={store}> <Provider store={store}>
<Router></Router> <App></App>
</Provider> </Provider>
</React.StrictMode>, </React.StrictMode>
document.getElementById("root") )
);

28
src/plugins/i18n/index.tsx

@ -0,0 +1,28 @@
import LanguageDetector from "i18next-browser-languagedetector"
import i18n from "i18next"
import enUsTrans from "@/assets/locales/en-us.json"
import zhCnTrans from "@/assets/locales/zh-cn.json"
import { initReactI18next } from "react-i18next"
i18n
.use(LanguageDetector) //嗅探当前浏览器语言
.use(initReactI18next) //init i18next
.init({
//引入资源文件
resources: {
en: {
translation: enUsTrans,
},
zh: {
translation: zhCnTrans,
},
},
//选择默认语言,选择内容为上述配置中的key,即en/zh
fallbackLng: "zh",
debug: false,
interpolation: {
escapeValue: false, // not needed for react as it escapes by default
},
})
export default i18n

5
src/route.tsx

@ -25,7 +25,6 @@ export default [
{ {
path: "/about", path: "/about",
component: lazy(() => import("@/views/About")), component: lazy(() => import("@/views/About")),
exact: false,
meta: { meta: {
auth: false, auth: false,
}, },
@ -33,7 +32,6 @@ export default [
children: [ children: [
{ {
path: "/about/test", path: "/about/test",
exact: true,
meta: { meta: {
auth: false, auth: false,
}, },
@ -45,7 +43,6 @@ export default [
{ {
path: "/home", path: "/home",
component: lazy(() => import("@/views/Home")), component: lazy(() => import("@/views/Home")),
exact: true,
loading: () => <Loading color="blue"></Loading>, loading: () => <Loading color="blue"></Loading>,
meta: { meta: {
auth: false, auth: false,
@ -54,7 +51,6 @@ export default [
}, },
{ {
path: "/", path: "/",
exact: true,
redirect: "/home", redirect: "/home",
}, },
{ {
@ -63,7 +59,6 @@ export default [
}, },
{ {
path: "*", path: "*",
exact: false,
component: Page404, component: Page404,
}, },
] ]

17
src/ui/Auth.tsx

@ -1,11 +1,11 @@
import React, { Component, ReactElement } from "react" import React, { Component, Fragment } from "react"
// 高阶组件,就是对原来的组件进行封装 // 高阶组件,就是对原来的组件进行封装
import { Route, Redirect, NavLink } from "react-router-dom" import { Route, NavLink } from "react-router-dom"
interface IProps { interface IProps {
needAuth?: boolean needAuth?: boolean
path: string path: string
exact?: boolean children: any
} }
class Auth extends Component<IProps> { class Auth extends Component<IProps> {
@ -14,21 +14,20 @@ class Auth extends Component<IProps> {
} }
render() { render() {
const { path, needAuth = false, exact = false } = this.props // 结构语法的概 const { path, needAuth = false } = this.props // 结构语法的概
if (!needAuth) { if (!needAuth) {
return ( return (
// 如果已经登陆,就直接显示原来的组件 // 如果已经登陆,就直接显示原来的组件
<Route exact={exact} path={path}> <Route path={path}>
{this.props.children} {this.props.children}
</Route> </Route>
) )
} else { } else {
return ( return (
<div> <Fragment>
<NavLink to="/login"></NavLink> <NavLink to="/login"></NavLink>
</Fragment>
{/* <Redirect to={{ pathname: '/login', state: { from: { path }} }} > </Redirect> */}
</div>
) )
} }
} }

6
src/views/About/index.tsx

@ -1,5 +1,5 @@
import React from "react" import React from "react"
import { useLocation, Route, Switch } from "react-router-dom" import { useLocation } from "react-router-dom"
function Test() { function Test() {
return <div>test</div> return <div>test</div>
@ -13,9 +13,9 @@ export default function (props: any) {
<div className="container mx-auto"> <div className="container mx-auto">
<div>AboutAAAasda </div> <div>AboutAAAasda </div>
<div>22{props.children}</div> <div>22{props.children}</div>
<Route path="/about/aa" exact={true}> {/* <Route path="/about/aa">
<Test></Test> <Test></Test>
</Route> </Route> */}
</div> </div>
) )
} }

28
src/views/Login/index.tsx

@ -1,32 +1,48 @@
import React from "react" import React, { useRef } from "react"
import cn from "classnames" import cn from "classnames"
import style from "./index.module.scss" import style from "./index.module.scss"
import { useLocation, Route, Switch } from "react-router-dom" import { useLocation, Route, Switch } from "react-router-dom"
import { useState } from "react" import { useState } from "react"
import Bubbles from "@/components/Loading/Bubbles" import Bubbles from "@/components/Loading/Bubbles"
import { Trans, Translation, useTranslation } from "react-i18next"
export default function Login(props: any) { export default function Login(props: any) {
const [isSuccess, setIsSuccess] = useState(false) const [isSuccess, setIsSuccess] = useState(false)
const [WelcomeText, setWelcomeText] = useState("青铜时代2021") const [usename, setUsername] = useState("23")
const [password, setPassword] = useState("")
const { t ,i18n} = useTranslation()
function clickLogin(event: any) { function clickLogin(event: any) {
event.preventDefault() event.preventDefault()
setIsSuccess(true) setIsSuccess(true)
setTimeout(() => { setTimeout(() => {
setUsername('')
setPassword('')
setIsSuccess(false) setIsSuccess(false)
}, 2000) }, 2000)
} }
return ( return (
<div className={cn(style.login, style.page)}> <div className={cn(style.login, style.page)}>
<div style={{background:"red"}}>
<button onClick={()=>i18n.changeLanguage(i18n.language=='en'?'zh':'en')}>{i18n.language=='en'?'zh':'en'}</button>
<h1>{t('home')}</h1>
<h1>{usename}</h1>
<h1>{password}</h1>
<h2><Trans>home</Trans></h2>
<Translation>{t => <h3>{t('home')}</h3>}</Translation>
</div>
<div className={cn(style.wrapper, isSuccess ? style["form-success"] : "")}> <div className={cn(style.wrapper, isSuccess ? style["form-success"] : "")}>
<div className={cn(style.container)}> <div className={cn(style.container)}>
<h1>{WelcomeText}</h1> <h1><Trans>login.title</Trans></h1>
<form className={cn(style.form)}> <form className={cn(style.form)}>
<input type="text" placeholder="Username" /> <input type="text" value={usename} onChange={(e)=>setUsername(e.target.value)} placeholder={t('login.username_placeholder')} />
<input type="password" placeholder="Password" autoComplete="" /> <input type="password" value={password} onChange={(e)=>setPassword(e.target.value)} placeholder={t('login.password_placeholder')} autoComplete="" />
<button type="submit" id={cn(style["login-login"])} onClick={clickLogin}> <button type="submit" id={cn(style["login-login"])} onClick={clickLogin}>
Login <Trans>login.btnText</Trans>
</button> </button>
</form> </form>
</div> </div>

4
vite.config.ts

@ -1,5 +1,5 @@
import { defineConfig } from "vite"; import { defineConfig } from "vite";
import reactRefresh from "@vitejs/plugin-react-refresh"; import react from "@vitejs/plugin-react-swc";
import WindiCSS from "vite-plugin-windicss"; import WindiCSS from "vite-plugin-windicss";
const { resolve } = require("path"); const { resolve } = require("path");
@ -15,5 +15,5 @@ export default defineConfig({
resolve: { resolve: {
alias: [{ find: "@", replacement: resolve(__dirname, "src") }], alias: [{ find: "@", replacement: resolve(__dirname, "src") }],
}, },
plugins: [WindiCSS(), reactRefresh()], plugins: [WindiCSS(), react()],
}); });

Loading…
Cancel
Save