相关文件的结构

        

  1. request.js文件中创建axios实例并暴露
    
    import { ElNotification } from 'element-plus'
    import axios from 'axios'
    import store from '../store'
    import Nprogress from 'nprogress'
    import router from '../router'
    // const app = createApp(App)
    const service = axios.create({
      // 这里的api是用做请求代理的,baseURL会自动添加到url之前,url在后续的fetch.js文件中动态传入
      baseURL: 'api',
      timeout: 5000, // 请求超时毫秒
    })
    /**
     * 拦截器
     */
    // 创建实例后拦截,可以进行添加token到请求头部等操作
    service.interceptors.request.use(config => {
      // if (store.getters.getToken) {
        config.headers['X-Token'] = store.getters.getToken
        Nprogress.start()
        return config
      // }
    }, error => {
      return Promise.reject(error)
    })
    // 请求完成后拦截,可在此做一系列通用操作
    service.interceptors.response.use(function ({data}) {
      // 2xx状态码会触发该函数
      Nprogress.done()
      if (data.success || data.code === 200) {
        return data
      } else {
        ElNotification({
          type: 'error',
          title: '操作失败',
          message: data.msg
        })
      }
    }, function (error) {
      // 超出2xx状态码会触发该函数
      Nprogress.done()
      ElNotification({
        type: 'error',
        title: '操作失败',
        message: error
      })
    })
    /**
     * 移除拦截器
     * service.interceptors.request.eject()
     */
    export default service
    // 关于api的代理,在vite.config.js中
    import { defineConfig, loadEnv } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueJsx from '@vitejs/plugin-vue-jsx'
    import { resolve } from 'path'
    export default defineConfig(({command, mode}) => {
      const env = loadEnv(mode, process.cwd(), '')
      return {
        plugins: [vue,vueJsx()],
        envPrefix:  ['VITE', 'VUE'], // 环境变量前缀
        base: '/',
        build: {
          outDir: 'dist',
        },
        server: { 
          port: 3001,
          host: '127.0.0.1',
          proxy: {            // 请求代理
            '/api': {
              target: 'http://' + env.VUE_APP_BASE_API, // 相关环境变量配置在另一篇博客有哦,也可以直接写你的目标服务器地址
              changeOrigin: true,
              rewrite: (path) => path.replace(/^\/api/, '/')
            }
          },
        },
        // 目录别名
        resolve: {
          alias: {
            '@': resolve(__dirname, '.', 'src')
          }
        }
      }
    })
    

  2. fetch.js中引入axios实例(可以在这里写自己的处理代码)
    import service from './request'
    export default function fetch({
      method="get",
      url,
      data,
      params
    }) {
      let option = {
        method,
        url,
        data,
        params
      }
      // 这里传入的option对象里的配置(如:url,method等)会自动覆盖原来初始化定义的axios里的相关定义
      // 所以初始化并未定义这些,因为不同请求方法的参数不同
      return service(option)
    }
    
    
     
  3. index.js中引入fetch.js,将引入的fetch和其他文件中暴露的请求方法挂在到    app.config.globalProperties  
// index.js
import fetch from './fetch'
import * as login from './login'
const service = {
  fetch,
  ...login
}
// const serviceProxy = createProxy(service)
export default {
  install: (app) => {
    app.config.globalProperties.$service = service
  }
}

// login.js

export function login(data){
  return this.fetch({
    method: 'post',
    url: 'xxxx',
    data
  })
}

4. 在项目main.js文件中引入service/index.js

import { createApp } from 'vue'
import App from './App.vue'
import service from './service'
const app = createApp(App)
app.use(service).mount('#app')

之后就可以在项目setup中通过getCurrentInstance().proxy使用之前挂载到app实例上的$service对象

import { reactive, ref, getCurrentInstance, onMounted, toRef, watch } from 'vue'
const { proxy } = getCurrentInstance()
proxy.$service.login(formData).then(() => {}).catch(() => {}).finally(() => {})
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐