vite 4 + react 18 + ts + react-router-dom v6 + zustand + antd 5
# 开发
npm run start
# 构建
npm run build
# 快速验证打包后的产物,模拟生产环境,`类 nginx` 的环境
# 执行该命令前请先构建项目 npm run build
npm run serve
# 或者 vite preview
备注:使用 dayjs, 与 antd 保持一致,纯了解 date-fns。
├── .vscode # 该项目 vscode 配置
├── config # 项目配置
│ └── proxy.ts # 代理
├── public # 资源文件
├── serve # node 服务
├── src # 源码目录
│ ├── component # 全局组件
│ ├── page # 页面组件
│ ├── route # 路由配置
│ ├── store # zustand:react hook 状态管理
│ ├── style # 样式自定义
│ ├── util # 工具库
│ │ └── index.ts # 工具方法
│ ├── app.tsx # 主组件
│ ├── index.css # 全局样式
│ ├── main.tsx # 主入口
│ └── vite-env.d.ts
├── .commitlintrc.js # git commit 规范配置
├── .eslintrc.js # eslint 配置
├── .gitignore # git忽略文件
├── .prettierrc.js # prettier 配置
├── index.html # html模版
├── package.json
├── README.md # 文档说明
├── tsconfig.json # ts 配置
└── tsconfig.node.json # ts node 配置
// 根目录store
// eg1: 简单使用 useBear.ts
import { create } from '@/store';
interface BearState {
bear: number;
increase: () => void;
reduce: () => void;
}
const useBearStore = create<BearState>()((set) => ({
bear: 0,
increase: () => set((state) => ({ bear: state.bear + 1 })),
reduce: () => set((state) => ({ bear: state.bear - 1 })),
}));
export default useBearStore;
// eg2: 持久化用户信息
import { create, persist, createJSONStorage } from '@/store';
interface UserInfoProps {
name: string;
phone: string | number;
}
interface UserInfoState {
isLogin: boolean;
token: string;
userInfo: UserInfoProps | null;
setUserInfo: (value: UserInfoProps) => void;
setToken: (token: string) => void;
reset: () => void;
}
/**
* 登录信息
* token信息
* 用户信息
* 持久化storage
*/
const useUserInfoStore = create<UserInfoState>()(
persist(
(set) => ({
isLogin: false,
token: '',
userInfo: null,
setUserInfo: (userInfo: UserInfoProps) => {
set(() => ({ userInfo, isLogin: true }));
},
setToken: (token: string) => {
set(() => ({ token }));
},
reset: () => {
set(() => ({ userInfo: null, isLogin: false, token: '' }));
},
}),
{
name: 'USER_INFO',
storage: createJSONStorage(() => localStorage),
},
),
);
export default useUserInfoStore;
快速验证打包后的产物,模拟生产环境,
类 nginx
的环境
# 执行该命令前请先构建项目 npm run build
npm run serve
参考 quick-nginx
- 备注:vite preview 支持这个功能
// vite.config.ts
preview: {
proxy: {
'/api': {
target: 'http:api.com',
changeOrigin: true,
},
}
};
- input
- number
- password
- textarea
- radio
- select
- checkbox
- switch
checkbox select radio 的 options 支持异步获取
- datepicker
- daterangepicker
- timepicker
- timerangepicker
- upload
- priceUnit
/demo/form/linkage
/demo/form/filter
colType 属性
colType | default | large |
---|---|---|
xxl | 4 | 8 |
xl | 6 | 12 |
lg | 8 | 16 |
md | 12 | 24 |
xs | 24 | 24 |
hook/useTable
util/fetch.ts
- 示例 page/demo/project/fetch
// https://github.com/vitejs/vite/issues/3033
// vite.config.ts
export default defineConfig({
plugins: [
// your plugins,
{
name: 'singleHMR',
handleHotUpdate({ modules }) {
modules.map((m) => {
m.importedModules = new Set();
m.importers = new Set();
});
return modules;
},
},
],
});
继续思考其他解决方案
Ant Design 支持最近 2 个版本的现代浏览器。如果你需要兼容旧版浏览器,请根据实际需求进行降级处理:样式兼容
- 方法一:引入 React 错误边界来解决该问题,通过友好的提醒,让用户刷新浏览器。
// src/component/error-boundary
import { ErrorBoundary as ErrorBoundaryComp } from 'react-error-boundary';
import styles from './index.module.scss';
function ErrorFallback({ error }: any) {
function goHome() {
location.href = '/';
}
return (
<div className={styles.ErrorBoundaryBox}>
<h1>Something went wrong: </h1>
<pre style={{ color: 'red' }}>{error.message}</pre>
<button onClick={() => location.reload()}>刷新试试</button>
<button onClick={goHome}>返回首页</button>
</div>
);
}
const ErrorBoundary: React.FC<any> = ({ children }) => {
return <ErrorBoundaryComp FallbackComponent={ErrorFallback}>{children}</ErrorBoundaryComp>;
};
export default ErrorBoundary;
// src/component/layout
<ErrorBoundary>
<Outlet />
</ErrorBoundary>
- 方法二:检测网页更新并通知用户刷新,支持 vite、umijs 和 webpack 插件。例如:plugin-web-update-notification
我们使用
react 错误边界
完全可以自己实现类似检测网页更新的功能。