Vue3+uniapp 封装axios

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.完成了快去试试吧,整体的文件

在这里插入图片描述

### 封装通用 Axios Request 方法 为了在 Vue2 的 UniApp 项目中创建一个类似于 Vue Axios 的 `request` 方法,可以通过以下方式实现: #### 创建请求工具类文件 首先,在项目的 `utils` 文件夹下新建名为 `request.js` 的文件。此文件用于定义所有 HTTP 请求的基础设置和拦截器。 ```javascript // utils/request.js import axios from &#39;axios&#39;; const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, // api base_url timeout: 5000 // 请求超时时间 }); // 请求拦截器 service.interceptors.request.use( config => { // 在发送请求之前做些什么 const token = uni.getStorageSync(&#39;token&#39;); if (token) { config.headers[&#39;Authorization&#39;] = `Bearer ${token}`; } return config; }, error => { // 对请求错误做些什么 Promise.reject(error); } ); // 响应拦截器 service.interceptors.response.use( response => { // 对响应数据做点什么 const res = response.data; // 如果返回的状态码不是200,则认为是有误 if (res.code !== 200) { Message({ message: res.message || "Error", type: "error" }); return Promise.reject(new Error(res.message || "Error")); } else { return res; } }, error => { console.log("err" + error); // 输出报错信息到控制台 Message({ message: error.message, type: "error" }); return Promise.reject(error); } ); export default function request(options){ let {url,params,data,method} = options; return new Promise((resolve,reject)=>{ service({url:url,params:params,data:data,method}) .then(response=>{ resolve(response)}) .catch(err=>{ reject(err) }) }) } ``` 这段代码实现了基本的HTTP客户端配置以及请求/响应处理逻辑[^1]。 #### 使用封装后的 API 进行调用 当完成了上述工作之后就可以轻松地在整个应用程序里边使用这个自定义的方法来进行各种类型的API交互了: ```javascript // example.vue <template> <!-- 组件模板 --> </template> <script> import request from &#39;@/utils/request&#39; export default { name: &#39;ExampleComponent&#39;, methods:{ async fetchData(){ try{ const result = await request({ method:&#39;POST&#39;, url:&#39;/api/exampleEndpoint&#39;, data:{account:"admin",pwd:123}, }); console.log(result); } catch(e){ console.error(`Failed to fetch data`, e); } } } }; </script> ``` 这里展示了如何利用刚刚建立起来的服务端通信机制去获取远程服务器上的资源并打印出来[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值