在这里插入图片描述

安装:

cnpm i axios -S

测试:

<script>
import { mapMutations } from 'vuex';
import axios from "axios";

export default {
  created(){
    axios('http://xxxxxx.com/api/agreement').then(function (response) {
      console.log(response);
    })
  }
}
</script>

进行跨域处理:

在vue.config.js( 如果没有就新建 )中配置devServer

const path = require("path");
function resolve(dir) {
  return path.join(__dirname, dir);
} 
module.exports = {
  chainWebpack: config => { // 这是对@路径的配置
    config.resolve.alias
      .set("@", resolve("src"))
      .set("assets", resolve("src/assets"))
      .set("components", resolve("src/components"))
      .set("public", resolve("public"));
  },
  devServer: {
    open: true,
    host: 'localhost',
    port: 8000,
    https: false,
    // 1、以上的ip和端口是我们本机的;下面为需要跨域的
    // 2、如果服务端已支持跨域,则下面跨域配置可忽略
    // 3、打包上线后,以下跨域配置可忽略,devServer的配置不会执行
    
    proxy: { //配置跨域
      '/api': {
        target: 'http://xxxxxx.com', //这里后台的地址模拟的;应该填写你们真实的后台接口
        ws: true,
        changOrigin: true, //允许跨域
        pathRewrite: {
          '^/api': '' //请求的时候使用这个api就可以
        }
      }
    }
    
    // proxy: { //如果配置了环境变量使用这个
    //   '/api': { 
    //     target: process.env.VUE_APP_BASE_URL, 
    //     ws: true,
    //     changOrigin: true, //允许跨域
    //     pathRewrite: {
    //       '^/api': '' //请求的时候使用这个api就可以
    //     }
    //   }
    // }
  }
}

配置环境变量

1、在package.json同级目录下新建 .env.production 生产模式和 .env.development 开发模式

2、设置在不同环境下要使用的变量;例如

// 生产模式
NODE_ENV = production
VUE_APP_BASE_URL="/api"
// 开发模式
NODE_ENV = development
VUE_APP_BASE_URL="/api"

第一行的 NODE_ENV 是告诉系统这是什么环境的文件夹

这里面其中的 VUE_APP_ 这个是项目固定写死的,不可更改,其后面的名称可以自己随便取,在这里我取的名字为 BASE_URL

3、在package.json 文件夹找到scripts 利用 --mode 来分配我们项目跑起来的指令分别对应的是生产模式开发模式 。就是根据你启动或者打包的命令获取对应的配置文件中的变量

 "scripts": {
    "serve": "vue-cli-service serve --mode development",
    "build": "vue-cli-service build --mode production",
    "lint": "vue-cli-service lint"
  },

二次封装axios

1、在 src 目录下新建 utils 目录,然后新建request.js文件;

//对axios进行二次封装
import axios from "axios"
 
//利用axios对象的方法create,去创建一个axios实例
export function api(config) {
  
  const api = axios.create({
    // baseURL: 'http://xxxxxx.com:8080', 
    // baseURL: '/api', // 如果配置了跨域,通过/api别名指定后端路由
    baseURL: process.env.VUE_APP_BASE_URL, // 如果配置环境变量,使用这个即可
    
    timeout: 5000,
    headers:{
    },
  })

  // 请求拦截处理
  api.interceptors.request.use(config => {
    return config
  }, err => {
    // 请求发生错误时的相关处理 抛出错误
    return Promise.reject(err)
  })
  api.interceptors.response.use(res => {
     
    return res
  }, err => {
    // 服务器响应发生错误时的处理
    Promise.reject(err)
  })

  return api(config)
}

到这一步即可使用axios,但并未对请求拦截器和响应拦截器进行什么操作

直接使用
<script>
import { api } from "@/utils/request.js";

export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
   created(){
    api({
      url:'/web/getAllDeptList'
    }).then(res=>{ })
  }
}
</script>

2、在src目录下新建api文件夹,用于存放不同模块的请求
如home.js:

import {api} from './request'

// 用户信息
export const agreement = ()=> {
  return api({url:'/agreement'})
}

3、调用请求

<script>
import { agreement } from 'api/home'

export default {
  async created(){
    let res = await agreement()
    console.log(res);
  }
}
</script>

至此axios就已经简单的进行了二次封装

对post和get进行封装

//对axios进行二次封装
import axios from "axios"
 
//利用axios对象的方法create,去创建一个axios实例
function api(config) {
  const api = axios.create({
    baseURL: process.env.VUE_APP_BASE_URL, // 配置环境变量,使用不同的baseURL
    timeout: 5000,
    headers:{
    },
  })

  // 请求拦截处理
  api.interceptors.request.use(config => {
    return config
  }, err => {
    // 请求发生错误时的相关处理 抛出错误
    return Promise.reject(err)
  })
  api.interceptors.response.use(res => {
     
    return res
  }, err => {
    // 服务器响应发生错误时的处理
    Promise.reject(err)
  })
  
  return api(config)
}

let http = {
  get:( url, params={},config={} )=>{
    return new Promise((resolve,reject) => {
      api({
        url:url,
        method:'GET',
        params:params,
        ...config
      }).then(res =>{
        resolve( res )
      }).catch(error =>{
        reject(error)
      })
    })
  },
  
  post:( url, data={},config={} )=>{
    return new Promise((resolve,reject) => {
      api({
        url,
        method:'POST',
        data,
        ...config
      }).then(res =>{
        resolve( res.data )
      }).catch(error =>{
        reject(error)
      })
    })
  },
}

//最后一步 暴露出去实例导出
export default http

在home.js中修改请求

import http from 'utils/request.js'

// 用户信息
export const agreement = ()=> {
  return http.get('/agreement', {}, { loading: true })
}
<script>  // 不对请求进行分模块处理,直接在页面中调用的方式
  import http from '@/utils/request';

  export default {
    name: "HelloWorld",
    data() {
      return {
      };
    },
    created() {

      http.get('pet/1',{},{loading: true}).then(res => {
        console.log(res,'aaaaaa');
      })

    },
    mounted() {

    },
    methods: {
    }
  };
</script>

添加lodaing组件

1、在utils目录下新建loading.js文件

import { Loading } from 'element-ui';
let loadingBoolean = null;
let loadingNumber = 0;

// 显示lodaing
const showLoading = ()=>{
  if( loadingNumber == 0 ){
    loadingBoolean = Loading.service({ fullscreen: true });
  }
  loadingNumber++
}

// 为避免在请求时使用了async/await造成多个请求的loading错乱,需要是防抖节流
// var _ = require('lodash'); // 工具库,使用防抖函数

//在一定时间内,关掉所有的loading 
// let newHideLoading = _.debounce(() => {
//   if (loadingBoolean) {
//       loadingBoolean.close()
//       loadingBoolean = null
//   }
// }, 1000)

// 隐藏lodaing
const hideLoading = ()=>{
  loadingNumber--
  if( loadingNumber == 0 ){
    // newHideLoading()
    debounce(()=>{
      if (loadingBoolean) {
        loadingBoolean.close()
        loadingBoolean = null
      }
    },2000)()
  }
}

// 防抖函数
function debounce(fun,time){
  let timer = null;
  return function (){
    clearTimeout(timer)
    timer = setTimeout(fun,time)
  }
}

export { showLoading,hideLoading }

也可以使用工具库 lodash 中防抖函数,也就是上面代码中注释掉的方式
安装:npm i --save lodash

2、在request.js文件中调用loading

//对axios进行二次封装
import axios from "axios"
import { showLoading,hideLoading } from "./loading";
 
//利用axios对象的方法create,去创建一个axios实例
function api(config) {

  const api = axios.create({
    baseURL: process.env.VUE_APP_BASE_URL, // 配置环境变量,使用不同的baseURL
    timeout: 5000,
    headers:{
    },
  })

  // 请求拦截处理
  api.interceptors.request.use(config => {
    if( config.loading ){ // 开启lodaing
      showLoading()
    }

    return config
  }, err => {
    // 请求发生错误时的相关处理 抛出错误
    return Promise.reject(err)
  })
  api.interceptors.response.use(res => {
    if( res.status ){ // 关闭loading
      hideLoading() 
    }

    return res
  }, err => {
    // 服务器响应发生错误时的处理
    Promise.reject(err)
  })
  
  return api(config)
}

let http = {
  get:( url, params={},config={} )=>{
    return new Promise((resolve,reject) => {
      api({
        url:url,
        method:'GET',
        params:params,
        ...config
      }).then(res =>{
        resolve( res )
      }).catch(error =>{
        reject(error)
      })
    })
  },
  
  post:( url, data={},config={} )=>{
    return new Promise((resolve,reject) => {
      api({
        url,
        method:'POST',
        data,
        ...config
      }).then(res =>{
        resolve( res.data )
      }).catch(error =>{
        reject(error)
      })
    })
  },
}

//最后一步 暴露出去实例导出
export default http

以上配置任何一步都是可以单独拎出来使用的,视项目情况而定

参考链接:https://segmentfault.com/a/1190000014702852

Logo

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

更多推荐