前言
正在寫一個 以taro3 + vue3 + webpack4為基礎框架的微信小程序,之前一直沒有記咋寫的,現在總結記錄一下。uniapp + vite 的后面出。
文章目錄
- 前言
- 一、創建環境配置文件
- 二、 配置 Taro 環境變量
- 三、 創建請求封裝
- 四、如何上傳到微信小程序體驗版
- 1.第二點的時候,咱們已經配置好了運行每個環境的命令了,這個之后,只需要執行命令,例如:
- 2.打開 微信開發者工具,打開 dist 文件夾
- 3. 檢查上傳的版本
一、創建環境配置文件
在 Taro3 框架中,區分環境并配置不同的請求域名(baseURL)可以結合 Taro 提供的環境變量和配置文件來實現。
詳細配置,參考官網: 編譯配置
在項目根目錄下創建 config
文件夾,并添加不同環境的配置文件:
二、 配置 Taro 環境變量
在 package.json
中添加環境變量配置:
一般我們是用命令行創建的項目,都會寫好的,這個自己校對一下就好咯
{"scripts": {"dev:weapp": "taro build --type weapp --watch","build:weapp:dev": "cross-env NODE_ENV=development taro build --type weapp","build:weapp:test": "cross-env NODE_ENV=test taro build --type weapp","build:weapp:prod": "cross-env NODE_ENV=production taro build --type weapp"}
}
三、 創建請求封裝
在 src/utils
src/server
目錄下創建 request.ts
文件,使用 Taro 的 request 方法:
這里是基于
Taro.request
api哈, 官網直通道:https://docs.taro.zone/docs/apis/network/request/
// src/utils/request.js
import Taro from '@tarojs/taro';
import { baseUrlMap } from '@/config'; // 環境配置映射表// 請求配置
const defaultConfig = {baseURL: baseUrlMap[process.env.NODE_ENV || 'development'],timeout: 10000,header: {'content-type': 'application/json','X-Requested-With': 'XMLHttpRequest'}
};// 請求隊列,用于取消重復請求
const requestQueue = new Map();// 生成請求唯一標識
function generateRequestKey(config) {const { method, url, data } = config;return [method, url, JSON.stringify(data)].join('&');
}// 添加請求到隊列
function addRequestToQueue(config) {const requestKey = generateRequestKey(config);const abortController = new AbortController();requestQueue.set(requestKey, abortController);return abortController;
}// 從隊列中移除請求
function removeRequestFromQueue(config) {const requestKey = generateRequestKey(config);requestQueue.delete(requestKey);
}// 取消指定請求
function cancelRequest(config) {const requestKey = generateRequestKey(config);const abortController = requestQueue.get(requestKey);if (abortController) {abortController.abort();removeRequestFromQueue(config);}
}// 取消所有請求
function cancelAllRequests() {requestQueue.forEach(abortController => {abortController.abort();});requestQueue.clear();
}class Request {constructor(config) {this.config = config;this.interceptors = {request: [],response: []};}// 添加請求攔截器useRequestInterceptor(fulfilled, rejected) {this.interceptors.request.push({ fulfilled, rejected });return this;}// 添加響應攔截器useResponseInterceptor(fulfilled, rejected) {this.interceptors.response.unshift({ fulfilled, rejected });return this;}// 執行請求攔截器鏈async runRequestInterceptors(config) {let interceptedConfig = { ...config };for (const interceptor of this.interceptors.request) {try {if (interceptor.fulfilled) {interceptedConfig = await interceptor.fulfilled(interceptedConfig);}} catch (error) {if (interceptor.rejected) {await interceptor.rejected(error);}throw error;}}return interceptedConfig;}// 執行響應攔截器鏈async runResponseInterceptors(response) {let interceptedResponse = { ...response };for (const interceptor of this.interceptors.response) {try {if (interceptor.fulfilled) {interceptedResponse = await interceptor.fulfilled(interceptedResponse);}} catch (error) {if (interceptor.rejected) {await interceptor.rejected(error);}throw error;}}return interceptedResponse;}// 通用請求方法async request(options) {// 合并默認配置const mergedOptions = {...this.config,...options,url: this.config.baseURL + options.url};try {// 執行請求攔截器const interceptedOptions = await this.runRequestInterceptors(mergedOptions);// 處理取消請求邏輯const abortController = addRequestToQueue(interceptedOptions);interceptedOptions.signal = abortController.signal;// 發送請求const response = await Taro.request(interceptedOptions);// 從隊列中移除請求removeRequestFromQueue(interceptedOptions);// 執行響應攔截器return await this.runResponseInterceptors(response);} catch (error) {// 從隊列中移除請求removeRequestFromQueue(mergedOptions);// 處理取消請求錯誤if (error.name === 'AbortError') {console.log('請求已取消:', mergedOptions.url);return {statusCode: 499,errMsg: '請求已取消'};}// 處理其他錯誤throw error;}}// 快捷方法get(url, params = {}, config = {}) {return this.request({method: 'GET',url,data: params,...config});}post(url, data = {}, config = {}) {return this.request({method: 'POST',url,data,...config});}put(url, data = {}, config = {}) {return this.request({method: 'PUT',url,data,...config});}delete(url, params = {}, config = {}) {return this.request({method: 'DELETE',url,data: params,...config});}
}// 創建請求實例
const request = new Request(defaultConfig);// 添加請求攔截器 - 處理 token
request.useRequestInterceptor((config) => {// 添加 tokenconst token = Taro.getStorageSync('token');if (token) {config.header.Authorization = `Bearer ${token}`;}// 打印請求信息console.log(`[請求] ${config.method} ${config.url}`, config.data);return config;},(error) => {console.error('[請求錯誤]', error);return Promise.reject(error);}
);// 添加響應攔截器 - 處理業務狀態碼
request.useResponseInterceptor((response) => {console.log(`[響應] ${response.config.method} ${response.config.url}`, response.data);const { statusCode, data } = response;// 處理 HTTP 狀態碼if (statusCode < 200 || statusCode >= 300) {throw new Error(`HTTP錯誤 ${statusCode}`);}// 處理業務狀態碼 (根據后端規范調整)if (data.code === 200) {return data.data || true;} else if (data.code === 401) {// 未登錄或 token 過期Taro.showToast({title: '請先登錄',icon: 'none'});// 跳轉到登錄頁setTimeout(() => {Taro.navigateTo({ url: '/pages/login/index' });}, 1000);return Promise.reject(new Error('未登錄'));} else {// 其他業務錯誤Taro.showToast({title: data.message || '請求失敗',icon: 'none'});return Promise.reject(new Error(data.message || '請求失敗'));}},(error) => {console.error('[響應錯誤]', error);// 顯示錯誤信息Taro.showToast({title: error.message || '網絡請求失敗',icon: 'none'});return Promise.reject(error);}
);export default request;
export { cancelRequest, cancelAllRequests };
從上面的代碼可以看出來,我們在封裝request的時候,要注意以下幾點:
- 多環境支持:根據 process.env.NODE_ENV 自動切換 API 基礎路徑
- 請求攔截器:支持添加多個請求攔截器,可用于添加認證信息、日志記錄等
- 響應攔截器:支持添加多個響應攔截器,可用于統一處理業務狀態碼、錯誤提示等
- 請求取消:支持取消單個請求或所有請求,防止重復請求
- 錯誤處理:統一處理網絡錯誤、業務錯誤,并提供友好提示
- 擴展性:可根據需求靈活添加更多功能,如請求重試、緩存等
四、如何上傳到微信小程序體驗版
1.第二點的時候,咱們已經配置好了運行每個環境的命令了,這個之后,只需要執行命令,例如:
# 開發環境打包
npm run build:weapp:dev# 測試環境打包
npm run build:weapp:test# 生產環境打包
npm run build:weapp:prod
打包后的文件會生成在dist目錄下。
2.打開 微信開發者工具,打開 dist 文件夾
3. 檢查上傳的版本