# 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