《微信小程序》第六章:参数定义与管理

系列文章

《微信小程序》https://blog.csdn.net/sen_shan/category_13069009.html

第五章:登录-API封装https://blog.csdn.net/sen_shan/article/details/153963486?spm=1011.2415.3001.5331

文章目录

目录

系列文章

文章目录

前言

参数定义

请求修改

调试与测试


前言

本文介绍了微信小程序中参数统一管理的实现方案。核心内容包括:

1)通过src/config/index.ts文件实现多环境配置管理,自动区分开发/测试/生产环境;

2)实例request.ts中应用

参数定义

建立src/config/index.ts文件

javascript 复制代码
// src/config/index.ts
type EnvFile = 'dev' | 'test' | 'prod'

function getEnv(): EnvFile { 
	// #ifdef H5
	  const m = import.meta.env.MODE   // vite 环境变量
	  if (m === 'production') return 'prod'
	  if (m === 'test' || m === 'gray') return 'test'
	  return 'dev'
	  // #endif
	
	  // #ifndef H5
	  const v = uni.getAccountInfoSync().miniProgram.envVersion
	  if (v === 'release') return 'prod'
	  if (v === 'trial') return 'test'
	  return 'dev'          // develop / experience
	  // #endif
}

/* 1. 与环境无关的常量 */
const COMMON = {
  TIMEOUT: 15000,
  PAGE_SIZE: 20,
  MAX_RETRY: 3,
  // 任意其他固定值
} as const

/* 2. 与环境有关的差异配置 */
const ENV_CONFIG = {
  dev: {
    API_BASE_URL: 'http://127.0.0.1:8080',
    API_KEY: 'ae139f8f6a8efc2a74a1e852c5cdaa43',
    TRACK_URL: 'http://127.0.0.1:8080',
    ENABLE_VCONSOLE: true,
  },
  test: {
    API_BASE_URL: 'https://test-api.xxx.com',
    API_KEY: 'test-key-123456',
    TRACK_URL: 'https://test-track.xxx.com',
    ENABLE_VCONSOLE: true,
  },
  prod: {
    API_BASE_URL: 'https://api.xxx.com',
    API_KEY: 'prod-key-abcdef',
    TRACK_URL: 'https://track.xxx.com',
    ENABLE_VCONSOLE: false,
  },
} as const

/* 3. 合并后一次性导出 */
export default {
  ...COMMON,
  ...ENV_CONFIG[getEnv()],
} as const

作 用:

根据运行平台与构建环境自动选取对应的后端地址、密钥及功能开关,并统一导出只读常量供全局使用。

核心思路

  1. 先判断平台

H5:读取 Vite 注入的 import.meta.env.MODE

小程序:读取微信/支付宝等宿主提供的 uni.getAccountInfoSync().miniProgram.envVersion

  1. 再映射到 3 套环境

dev | test | prod

  1. 最后把「与环境无关的常量」+「当前环境变量」合并成单例导出

请求修改

修改src\utils\request.ts文件

javascript 复制代码
import config from '@/src/config/index'
/* 配置 ------------------------------------------------------------------ */
const BASE_URL: string = config.API_BASE_URL //'http://8.130.11.167:8080'// 替换你的后端域名
const API_KEY: string = config.API_KEY
const TIMEOUT = config.TIMEOUT // ms

配置导入说明

  1. 配置来源

代码中所有 BASE_URL / API_KEY / TIMEOUT 等常量均统一从 @/src/config/index 自动读取。

该文件会根据运行平台(H5 / 小程序)与构建环境(dev / test / prod)动态返回对应的域名、密钥及功能开关,业务层无需再写 if/else 判断环境。

若后台域名或密钥发生变更,只需修改 src/config/index.ts ,无需逐文件替换。

完整代码如下:

javascript 复制代码
// 顶部引入
import { toastError } from './toast'
import config from '@/src/config/index'
/* 配置 ------------------------------------------------------------------ */
const BASE_URL: string = config.API_BASE_URL //'http://8.130.11.167:8080'// 替换你的后端域名
const API_KEY: string = config.API_KEY
const TIMEOUT = config.TIMEOUT // ms

/* 类型定义 --------------------------------------------------------------- */
export type Method = 'GET' | 'POST' | 'PUT' | 'DELETE'

export interface RequestOptions<T = any> {
  url: string
  method?: Method
  data?: T
  headers?: Record<string, string>
  noToken?: boolean // 跳过 token
  noBaseURL?: boolean // 跳过 baseURL
  timeout?: number
}

// 后端统一返回格式(按你的实际改)
export interface HttpResponse<T = any> {
  status_code: number
  status:string
  message: string
  data: T
}

/* 核心请求 --------------------------------------------------------------- */
export function request<R = any>(options: RequestOptions): Promise<HttpResponse<R>> {
  console.log(BASE_URL)
  console.log(API_KEY)
  return new Promise((resolve, reject) => {
    const token = uni.getStorageSync('token')
    const header: AnyObject = {
      'Content-Type': 'application/json; charset=utf-8',
      'x-api-key': API_KEY ,//'ae139f8f6a8efc2a74a1e852c5cdaa43',
      ...options.headers,
    }

    if (!options.noToken && token) header.Authorization = `Bearer ${token}`

    uni.request({
      url: options.noBaseURL ? options.url : `${BASE_URL}${options.url}`,
      method: options.method || 'GET',
      data: options.data || {},
      header,
      timeout: options.timeout || TIMEOUT,
      success: (res) => handleSuccess<R>(res, resolve, reject),
      fail: (err) => handleFail(err, reject),
    })
  })
}

/* 成功处理 --------------------------------------------------------------- */
function handleSuccess<R>(
  res: UniApp.RequestSuccessCallbackResult,
  resolve: (value: HttpResponse<R>) => void,
  reject: (reason?: any) => void,
) {
  const { statusCode, data } = res
  // 成功区间
  if (statusCode >= 200 && statusCode < 300) {
    const resp = data as HttpResponse<R>
    if (resp.status_code === 200) resolve(resp)
    else {
      toastError(resp.message)
      reject(resp)
    }
    return
  }
  // 401 登录态失效
  if (statusCode === 401) {
    const detail = (data as any)?.detail || '登录已过期'
    toastError(detail)
    uni.clearStorageSync()
    uni.reLaunch({ url: '/pages/login/index' })
    reject(new Error(detail))
    return
  }
  // 其他 4xx/5xx
  if (statusCode >= 300) {
    const detail = (data as any)?.detail || `请求失败(${statusCode})`
    toastError(detail)
    reject(new Error(detail))
    return
  }
}

/* 失败处理 --------------------------------------------------------------- */
function handleFail(err: any, reject: (reason?: any) => void) {
  toastError('网络异常')
  reject(err)
}

/* 上传文件 --------------------------------------------------------------- */
export function upload<R = any>(
  url: string,
  filePath: string,
  formData?: Record<string, any>,
  timeout = 30_000,
): Promise<R> {
  const token = uni.getStorageSync('token')
  return new Promise((resolve, reject) => {
    uni.uploadFile({
      url: `${BASE_URL}${url}`,
      filePath,
      name: 'file',
      formData,
      header: { Authorization: `Bearer ${token}` },
      timeout,
      success: (res) => {
        const data: HttpResponse<R> = JSON.parse(res.data)
        if (data.status_code === 0) resolve(data.data)
        else {
          uni.showToast({ title: data.message || '上传失败', icon: 'none' })
          reject(data)
        }
      },
      fail: reject,
    })
  })
}

/* 导出别名(可选)-------------------------------------------------------- */
export const http = {
  get<R>(url: string, params?: any, returnData = true) {
    return request<R>({ url, data: params }).then(res =>
      returnData ? res.data : res
    )
  },
  post<R>(url: string, data?: any, returnData = true) {
    return request<R>({ url, method: 'POST', data }).then(res =>
      returnData ? res.data : res
    )
  },
  put<R>(url: string, data?: any, returnData = true) {
    return request<R>({ url, method: 'PUT', data }).then(res =>
      returnData ? res.data : res
    )
  },
  delete<R>(url: string, returnData = true) {
    return request<R>({ url, method: 'DELETE' }).then(res =>
      returnData ? res.data : res
    )
  }
}

调试与测试

1.HBuilderX :运行 → 运行至浏览器→Chrome

2.启动后按 F12 打开开发者工具

3.输入任意不存在的用户名及密码,观察登录接口返回

4.输入正确的账号与密码

相关推荐
他们叫我秃子7 小时前
从 0 到 1,我用小程序 + 云开发打造了一个“记忆瓶子”,记录那些重要的日子!
前端·微信小程序·小程序·云开发
2501_915106328 小时前
iOS 反编译防护工具与实战组合 从静态侦察到 IPA 成品加固的工程化路径
android·ios·小程序·https·uni-app·iphone·webview
星光一影8 小时前
快递比价寄件系统技术解析:基于PHP+Vue+小程序的高效聚合配送解决方案
vue.js·mysql·小程序·php
苹果电脑的鑫鑫9 小时前
微信小程序原生如何使用画布生成名片
微信小程序·小程序
Dragon Wu10 小时前
Taro 自定义tab栏和自定义导航栏
前端·javascript·小程序·typescript·前端框架·taro
游戏开发爱好者811 小时前
iOS 26 iPhone 使用记录分析 多工具组合构建全方位设备行为洞察体系
android·ios·小程序·uni-app·cocoa·iphone·webview
星光一影1 天前
Java医院管理系统HIS源码带小程序和安装教程
java·开发语言·小程序
毕设源码-郭学长1 天前
【开题答辩全过程】以 基于微信小程序的个性化饮品定制点餐系统设计与实现为例,包含答辩的问题和答案
微信小程序·小程序
马尚道1 天前
uniapp陪诊小程序
微信小程序