ddStore
默认打开浏览器
textvite --open
1. 环境变量
textconsole.log(import.meta.env); // 获取 { BASE_URL: "/"; DEV: true; MODE: "development"; PROD: false; SSR: false; } // 类型来自 <reference types="vite/client" /> interface ImportMetaEnv { [key: string]: any BASE_URL: string MODE: string DEV: boolean PROD: boolean SSR: boolean }
自定义环境变量
text// 扩展类型 interface ImportMetaEnv { VITE_NAME: string; } // 预览线上 "preview": "vite preview --open"
text// https://vitejs.dev/config/ export default defineConfig((mode) => { console.log(mode.mode); // 环境模式 // 拼接当前环境文件名 let server: CommonServerOptions; const currEnvFileName = `.env.${mode.mode}`; // 使用dotev // 读取当前环境文件 const envData = fs.readFileSync(currEnvFileName); const envMap: DotenvParseOutput = dotev.parse(envData); server = { host: envMap.VITE_HOST, port: +envMap.VITE_PORT, proxy: { [envMap.VITE_BASE_URL]: { target: envMap.VITE_PROXY, }, }, }; return { plugins: [vue()], server, }; });
2. 动态管理图片
数据库只存取文件名
封装类方法获取所有文件图片,返回图片名对应的图片路径 ['文件名','path']
安装good-storage进行本地存储化
textstatic storageImgList() { this.imgList = goodStorage.get("imgList") || {}; if (!Object.keys(this.imgList).length) { // 如果为空,加载图片 this.loadAllImg(); goodStorage.set("imgList", this.imgList); } }
ESLint+Prettier
textcnpm i eslint@7.2.0 eslint-plugin-vue@7.20.0 vue-eslint-parser @typescript-eslint/parser @typescript-eslint/eslint-plugin -D npx eslint --init
配置
3. axios封装
- 封装类,类可以创建多个实例,适用范围更广,封装性更强
textclass Request { instance: AxiosInstance; constructor(config: AxiosRequestConfig) { this.instance = axios.create(config); } request(config: AxiosRequestConfig) { return this.instance.request(config); } }
-
封装拦截器
textthis.instance = axios.create(config); // 拿到当前实例拦截对象 this.interceptors = config.interceptors!; // 1. 定义全局请求拦截器 this.instance.interceptors.request.use( (res: AxiosRequestConfig) => { console.log('全局请求拦截'); return res; }, (err: any) => err ); // 2. 实例拦截器 this.instance.interceptors.request.use( this.interceptors.requestInterceptors, this.interceptors.requestInterceptorsCatch ); // 3. 实例响应拦截器 this.instance.interceptors.response.use( this.interceptors.responceInterceptors, this.interceptors.responceInterceptorsCatch ); // 全局相应拦截器保证最后执行 this.instance.interceptors.response.use( (res: AxiosResponse) => { console.log('全局响应拦截'); return res.data; }, (err: any) => err );拦截器的执行顺序为实例请求→类请求→实例响应→类响应(请求拦截器,先use的后执行,响应拦截器,先use的先执行)
-
封装request方法
textrequest(config: RequestConfig) { return new Promise((resolve, reject) => { // 对单个请求设置拦截器 if (config.interceptors?.requestInterceptors) { config = config.interceptors.requestInterceptors(config); } this.instance .request(config) .then((res) => { // 对单个请求设置响应拦截 if (config.interceptors?.responceInterceptors) { res = config.interceptors.responceInterceptors(res); } resolve(res); }) .catch((err) => { reject(err); }); }); }
textundefined -
-
封装其他方法
textget<T = any>(url: string, config?: AxiosRequestConfig): Promise<T> { return this.instance.get(url, config); } post<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> { return this.instance.post(url, data, config); } put<T = any>(url: string, data?: any, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> { return this.instance.put(url, data, config); } delete<T = any>(url: string, config?: AxiosRequestConfig): Promise<AxiosResponse<T>> { return this.instance.delete(url, config); }
- 基本使用
textimport allConf from '../config'; import Request from './request'; const request = new Request({ baseURL: allConf.baseApi, timeout: 20000, interceptors: { requestInterceptors: (config) => { console.log('实力请求拦截器'); return config; }, responceInterceptors: (res) => { console.log('实力响应拦截器'); return res.data; }, }, }); export default request; // category.ts import request from '../request'; import { ICategory } from './type'; class CategoryApi { async getCategoryListByFirstId(firstId: number) { return await request.get<ICategory[]>(`/ctgy/${firstId}`); } } const { getCategoryListByFirstId } = new CategoryApi(); export { getCategoryListByFirstId };
4. pinia集成
textconst useCtgyStore = defineStore('ctgy', () => { const firstCtgy = ref<IFirstCtgy[]>(); const getFirstCtgyAction = async () => { firstCtgy.value = (await getFirstCatrgoryList()).data; }; return { firstCtgy, getFirstCtgyAction, }; });
5. 自适应配置
-
样式重置包
textnpm install normalize.css -
postcss.config.cjs
textmodule.exports = { plugins: { // ... "postcss-px-to-viewport": { unitToConvert: "px", viewportWidth: 375, propList: ["*"], viewportUnit: "vw", fontViewportUnit: "vw", selectorBlackList: [], minPixelValue: 1, mediaQuery: false, replace: true, exclude: undefined, include: undefined, landscape: false, landscapeUnit: "vw", }, }, };