# react-vite **Repository Path**: zzzPython/react-vite ## Basic Information - **Project Name**: react-vite - **Description**: react react-redux redux react-router-dom less。less-module antd 组件动态引入 - **Primary Language**: TypeScript - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2022-09-21 - **Last Updated**: 2022-09-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # react-vite #### 介绍 typescript react react-redux redux react-router-dom less。less-module antd #### 软件架构 vite构建react项目 使用typescript react-router,react-redux,redux,antd, less typescript 实现 redux typescript 实现 axios(TODO) src/types 下存放 1. redux.d.ts(redux 所需范型) 2. axios.d.ts(axios所需范型) antd 组件库 (按需引入) ``` import vitePluginImp from "vite-plugin-imp"; vite.config.ts >> plugins >> vitePluginImp({ libList: [ { libName: "antd", style: (name) => `antd/es/${name}/style`, }, ], }) ``` 修改base 打包后 访问的地址是 /react-vite/ 开头 ``` vite.config.ts >> base: env.VITE_MODE == "production" ? "/react-vite/" : "/", ``` react vite react-router-dom 使用useRoutes 非根目录打包的问题 ``` 增加 basename={import.meta.env.BASE_URL} }> ``` css 预编译 less的模块化等 ``` css: { //* css模块化 modules: { // css模块化 文件以.module.[css|less|scss]结尾 generateScopedName: "[name]__[local]___[hash:base64:5]", hashPrefix: "prefix", }, //* 预编译支持less 并且设置主题颜色 preprocessorOptions: { less: { javascriptEnabled: true, modifyVars: { "primary-color": "#0fcb09", //设置antd主题色 "font-size-base": "20px", // 主字号 "@border-radius-base": "10px", }, }, }, } ``` 使用 ``` 1. 原生 element.style { --2e220fd2: 350px; --6cf08e2c: 33%; } width: var(--2e220fd2); 2. less 下 .item:extend(.base) { font-size: 25px; } @stepWidth:70px; @stepHeight:70px; @noActiveColor: rgba(83, 84, 85, 0.67); @activeColor:#646cff; ``` nginx 配置 ``` location /react-vite { alias /Users/zzz/project/webProject/reactProject/react-vite/dist; index index.html index.htm; try_files $uri $uri/ @routerReactVite; client_max_body_size 100m; gzip_static on; gzip_http_version 1.1; gzip_proxied expired no-cache no-store private auth; } location @routerReactVite { rewrite ^.*$ /react-vite/index.html last; } ``` 设置别名 @ # ``` vite.config.ts >> resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)), "#": resolve(__dirname, '/src/types'), }, extensions: [".js", ".ts", "tsx"], // 使用路径别名时想要省略的后缀名,可以自己 增减 }, ts 编译器识别 tsconfig.json >> compilerOptions 》》 paths "paths": { "@/*": ["./src/*"], "#/*": ["./src/types/*"] }, ``` 动态组件引用 查看 lib >> loadComponent.tsx 使用查看 component 》》 Codes/index.tsx 通过 import.meta.glob 导入模块 Promise 返回组件 实现代码 ``` import React from "react"; const modules = import.meta.glob('./../components/**/*.tsx') const errorComponentPath = '../components/ErrorComponent/index.tsx' const loadComponent = (dir: string, props: any) => { const Component = React.lazy(() => { return new Promise((resolve, reject) => { let path = '../' + dir console.log('LoadComponent', modules, path) // 开发 生产可用(build后) modules[path in modules? path: errorComponentPath]().then((Component: any) => { resolve(Component); },) // 仅测试 开大 可用 // import(`/src/${dir}`).then((Component) => { // resolve(Component) // }) }); }); return }; export default loadComponent ``` 使用 ``` const [component, setComponent] = useState(null); useEffect(() => { setComponent(loadComponent(`components/Codes/Code${code}/index.tsx`, {code: code})) }, [code]); return ( { {component ? component : null} } ) ``` 路由懒加载 ``` 使用lazy 加载组件 但是必须被 Suspense标签包裹 Suspense 的 fallback 是加载时展示的组件(不能懒加载loading) import React, {lazy} from 'react' const Detail = lazy(() => import('./../pages/Detail')) import React, {Suspense} from 'react' }> ``` 启动命令控制模式 mode package.json 》》 scripts value值后 加 --mode 【development?。。。 xxx】 可随意写 但是 需要在跟目录下添加 .env.xxx 文件 并且要下边包含你添加的 变量 增加 环境变量 import.meta.env ``` vite-env.d.ts(可换名字) 用来增加 import.meta.env 中的key (必须是 VITE_ 开头的) eg: /// interface ImportMetaEnv { readonly VITE_MODE: string readonly VITE_APP_BASE_URL: string .... } interface ImportMeta { readonly env: ImportMetaEnv } ``` redux 使用 查看 src/redux 文件夹下 ``` src | └─── contions │ │ │ └─── Count │ │ └─ index.tsx │ └─── Person │ └─ index.tsx └─── redux │ │ store.ts │ │ constant.ts │ │ │ └───actions │ │ │ count.ts │ │ │ persion.ts │ │ │ └───reducers │ │ count.ts │ │ index.ts │ │ person.ts │ │ └──── types │ reducer.d.ts ``` src/contions 1.需要在被 Provider 标签包裹 ``` import {Provider} from 'react-redux' import store from "@/redux/store"; ..... ``` ``` store.ts /** * redux最核心的管理模块 */ import {legacy_createStore as createStore, applyMiddleware} from "redux"; import thunk from "redux-thunk"; import {composeWithDevTools} from "redux-devtools-extension"; import reducers from './reducers' export default createStore(reducers,composeWithDevTools(applyMiddleware(thunk))) ``` ``` constant.ts // count 的actions export enum CountActionTypes { EMPTy='', INCREMENT='increment', //加法 DECREMENT='decrement' // 减法 } // 用户的 actions export enum UserActionType { ADD_PERSON = 'addPerson', // 添加用户 } ``` ``` reducers/index.ts import {combineReducers} from "redux"; import count from './count' import {person} from "@/redux/reducers/person"; export default combineReducers({ count: count, persons: person, }) ``` ``` count.ts import {CountStatus, ReducerType} from "#/reducer"; import {CountActionTypes} from "@/redux/constant"; const count:ReducerType = (preState=0, action) => { const {type, data} = action; switch (type) { case '': return 0 default: return preState } } export default count ``` ``` count >> index.jsx import React, {ComponentPropsWithRef, Dispatch, ElementRef, MutableRefObject, useRef} from 'react'; import {connect} from 'react-redux' import {increment, decrement} from '@/redux/actions/count' import {AllStatusType} from "#/reducer"; interface PropsType { count: number, persons: number, addNum(data:number): void subtraction(data:number): void } function Count(props: PropsType) { const selectRef = useRef>(null) console.log('Count 组件中', props, selectRef) function add() { console.log('值为', selectRef.current?.value) const {current: {value}} = selectRef props.addNum(value*1) } function subtraction() { const {current: {value}} = selectRef props.subtraction(value*1) } return (

Count组件 加减法{props.count}====================={props.persons}

); } export default connect( (state:AllStatusType) => ({count: state.count, persons: state.persons.length}), (dispatch) => { return { addNum: (data: number) => {dispatch(increment(data))}, subtraction: (data: number) => {dispatch(decrement(data))}, } } )(Count); 或者 export default connect( (state:AllStatusType) => ({count: state.count, persons: state.persons.length}), { addNum: increment(data), subtraction: decrement(data), } )(Count); ``` #### 安装教程 详情查看 package.json scripts 1. pnpm install 2. pnpm run dev 3. pnpm run build