Vue实战之从零搭建Vite2+Vue3全家桶(二)

1,817 阅读2分钟

前言

上一篇从整体架构上基本上已经搭建完成,遗漏了http请求工具,本篇主要是完善补充http请求工具axios的使用。

传送门

Vue实战之从零搭建Vite2+Vue3全家桶(一)

基于Vue的架构设计

http请求工具

这里采用\textrm\color{red}{axios}来进行http请求调用

安装axios

  npm install axios -s

封装axios请求,新建request.js

  import axios from 'axios'
  import {
    ElLoading,
    ElMessage
  } from 'element-plus';
  //创建axios的一个实例 
  const instance = axios.create({
    baseURL: import.meta.env.VITE_APP_URL, //接口统一域名
    timeout: 5000, //设置超时
    headers: {
      'Content-Type': 'application/json;charset=UTF-8;',
    }
  })
  let loading;
  //正在请求的数量
  let requestCount = 0
  //显示loading
  const showLoading = () => {
    if (requestCount === 0 && !loading) {
      loading = ElLoading.service({
        text: "Loading  ",
        background: 'rgba(0, 0, 0, 0.7)',
        spinner: 'el-icon-loading',
      })
    }
    requestCount++;
  }
  //隐藏loading
  const hideLoading = () => {
    requestCount--
    if (requestCount == 0) {
      loading.close()
    }
  }
  // instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
  // instance.defaults.headers.get['Content-Type'] = 'application/x-www-form-urlencoded';
  // instance.defaults.transformRequest = [function (data) {
  //   let ret = ''
  //   for (let it in data) {
  //     ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
  //   }
  //   return ret
  // }]
  //请求拦截器 
  instance.interceptors.request.use((config) => {
    showLoading()
    // 每次发送请求之前判断是否存在token,如果存在,则统一在http请求的header都加上token,不用每次请求都手动添加了
    const token = window.localStorage.getItem('token');
    token && (config.headers.Authorization = token)
    //若请求方式为post,则将data参数转为JSON字符串
    if (config.method === 'POST') {
      config.data = JSON.stringify(config.data);
    }
    return config;
  }, (error) =>
    // 对请求错误做些什么
    Promise.reject(error));

  //响应拦截器
  instance.interceptors.response.use((response) => {
    hideLoading()
    //响应成功
    return response.data;
  }, (error) => {
    console.log(error)
    //响应错误
    if (error.response && error.response.status) {
      const status = error.response.status
      switch (status) {
        case 400:
          message = '请求错误';
          break;
        case 401:
          message = '请求错误';
          break;
        case 404:
          message = '请求地址出错';
          break;
        case 408:
          message = '请求超时';
          break;
        case 500:
          message = '服务器内部错误!';
          break;
        case 501:
          message = '服务未实现!';
          break;
        case 502:
          message = '网关错误!';
          break;
        case 503:
          message = '服务不可用!';
          break;
        case 504:
          message = '网关超时!';
          break;
        case 505:
          message = 'HTTP版本不受支持';
          break;
        default:
          message = '请求失败'
      }
      ElMessage.error(message);
      return Promise.reject(error);
    }
    return Promise.reject(error);
  });

  const axios = ({
    method,
    url,
    data,
    config
  }) => {
    method = method.toLowerCase();
    if (method == 'post') {
      return instance.post(url, data, { ...config })
    } else if (method == 'get') {
      return instance.get(url, {
        params: data,
        ...config
      })
    } else if (method == 'delete') {
      return instance.delete(url, {
        params: data,
        ...config
      })
    } else if (method == 'put') {
      return instance.put(url, data, { ...config })
    } else {
      console.error(`错误的请求方式:${method}`)
      return false
    }
  }
  export default axios

封装api请求

  import request from '@/utils/request.js'

  // 用户登录
  export function login(data) {
    return request({
      url: '/api/login',
      method: 'post',
      data,
      config: {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        },
        timeout: 10000
      }
    })
  }

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

vue组件中使用

  import { login } from '@/api/user'

  // 请求登录
  function onLogin() {
    login({ username: 'admin', pwd: 'admin' }).then(res => {
      // 业务逻辑
    })
  }