Vue3+uniapp 封装axios

发布于:2025-05-13 ⋅ 阅读:(11) ⋅ 点赞:(0)

1.第一步在项目根目录新建utils文件夹,里边新建两个文件request.js和uni-api-promisify.js

2.request.js 代码 要安装axios

import axios from 'axios'
import { showToast } from '@/utils/uni-api-promisify'

// 创建axios实例
const service = axios.create({
  baseURL: "https://api.buzznewsfull.com",
  timeout: 10000,
  headers: {
    'Content-Type': 'application/json;charset=utf-8'
  }
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么
    // 例如添加token
    const token = uni.getStorageSync('token')
    if (token) {
      config.headers['Authorization'] = 'Bearer ' + token
    }
    
    // 显示加载中提示
    uni.showLoading({
      title: '加载中...',
      mask: true
    })
    
    // 打印请求参数到控制台
    // console.log('请求配置:', config)
    // console.log('请求URL:', config.url)
    // console.log('请求方法:', config.method)
    
    // 区分显示GET和POST请求的参数
    if (config.method === 'get') {
      // console.log('GET请求参数:', config.params)
      // 打印完整URL,包括查询参数
      const fullUrl = new URL(config.url, config.baseURL)
      if (config.params) {
        Object.entries(config.params).forEach(([key, value]) => {
          fullUrl.searchParams.append(key, value)
        })
      }
      // console.log('完整请求URL:', fullUrl.href)
    } else {
      // console.log('POST请求参数:', config.data)
    }
    
    return config
  },
  error => {
    // 对请求错误做些什么
    // console.log(error)
    uni.hideLoading()
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    uni.hideLoading()
    
    const res = response.data
    
    // 统一处理业务错误
    if (res.code !== 20000) {
      // 显示错误信息
      showToast({
        title: res.message || '操作失败',
        icon: 'none'
      })
      
      // 需要登录的状态码
      const loginRequiredCodes = [50008, 50012, 50014]
      if (loginRequiredCodes.includes(res.code)) {
        // 清除本地存储的用户信息
        uni.removeStorageSync('token')
        uni.removeStorageSync('userInfo')
        
        // 重新登录
        uni.showModal({
          title: '登录失效',
          content: '你已被登出,可以取消继续留在该页面,或者重新登录',
          confirmText: '重新登录',
          success: ({ confirm }) => {
            if (confirm) {
              uni.reLaunch({
                url: '/pages/login/login'
              })
            }
          }
        })
      }
      
      // 返回带有错误信息的对象,而不是直接reject
      return {
        success: false,
        code: res.code,
        message: res.message || '操作失败'
      }
    } else {
      // 业务成功,返回数据
      return {
        success: true,
        code: res.code,
        message: res.message || '操作成功',
        data: res.data
      }
    }
  },
  error => {
    console.log('err' + error)
    uni.hideLoading()
    
    let message = '网络请求失败,请稍后重试'
    if (error.response) {
      const status = error.response.status
      message = `请求错误,状态码:${status}`
    } else if (error.message) {
      message = error.message
    }
    
    showToast({
      title: message,
      icon: 'none'
    })
    
    // 返回错误对象
    return {
      success: false,
      code: -1,
      message: message
    }
  }
)

export default service  

3.uni-api-promisify.js

export const showToast = (options) => {
  return new Promise((resolve, reject) => {
    uni.showToast({
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

export const showModal = (options) => {
  return new Promise((resolve, reject) => {
    uni.showModal({
      ...options,
      success: resolve,
      fail: reject
    })
  })
}

// 可以继续添加其他需要Promise化的API  

4.根目录新建api文件夹,里边新建user.js 放接口

5.注意get请求参数是params 进行参数拼接,post是data在请求体中

import request from '@/utils/request'

/**
 * 登录
 * @param {Object} data - 登录数据
 * @param {string} data.username - 用户名
 * @param {string} data.password - 密码
 */
export function login(data) {
  return request({
    url: '/api/user/login',
    method: 'post',
    data
  })
}

/**
 * 获取用户信息
 */
export function getInfo(params) {
  return request({
    url: '/api/user/info',
    method: 'get',
    params
  })
}

/**
 * 登出
 */
export function logout(data) {
  return request({
    url: '/api/user/logout',
    method: 'post',
    data
  })
}  

6.页面中使用

import { defineStore } from 'pinia'
import { login, getInfo, logout } from '@/api/user'

export const useUserStore = defineStore({
  id: 'user',
  state: () => ({
    token: uni.getStorageSync('token') || '',
    userInfo: JSON.parse(uni.getStorageSync('userInfo') || '{}')
  }),
  actions: {
    // 登录
    async login(userInfo) {
      const { username, password } = userInfo
      const res = await login({ username: username.trim(), password })
      
      if (res.success) {
        this.token = res.data.token
        uni.setStorageSync('token', res.data.token)
        await this.getInfo()
      }
      
      return res
    },
    
    // 获取用户信息
    async getInfo() {
      const res = await getInfo()
      
      if (res.success) {
        this.userInfo = res.data
        uni.setStorageSync('userInfo', JSON.stringify(res.data))
      }
      
      return res
    },
    
    // 登出
    async logout() {
      const res = await logout()
      
      if (res.success || res.code === 50008) {
        this.token = ''
        this.userInfo = {}
        uni.removeStorageSync('token')
        uni.removeStorageSync('userInfo')
      }
      
      return res
    }
  }
})  

6.完成了快去试试吧,整体的文件

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到