Vue中axios的使用以及拦截器封装

Vue中axios的使用以及拦截器封装

Vue中axios的使用

axios 是一个基于Promise 用于浏览器和nodejsHTTP 客户端,本质上也是对原生XHR的封装,只不过它是Promise的实现版本。在Vue项目中我们使用axios就比较常见。

单独使用

先了解axios的基本用法:获取一段实时的段子,显示在列表中,过程中有loading的效果。

先简单编一个按钮和表格(elementUI)

微信图片_20210323135654.png

    <template>
      <div class="main">
        <el-button type="primary" size="default" @click="getJokes"
          >获取一些段子</el-button
        >
        <el-table v-loading="loading" :data="jokeList" border stripe>
          <el-table-column prop="sid" label="段子编号" width="180">
            <template slot-scope="scope">
              <el-tag type="primary" disable-transitions>{{
                scope.row.sid
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="name" label="标题" width="180"> </el-table-column>
          <el-table-column prop="text" label="内容"> </el-table-column>
        </el-table>
      </div>
    </template>
复制代码

然后点击按钮就调用API获取内容,axios的基本用法就是:

     axios.get(APIURL).then(response => ())}
复制代码

我们在created或者mounted这两个钩子中放置axios异步请求(面试点),如果想在请求的发送和接受前后做一些个性化的事情,就可以使用axios的拦截器

    /* 请求拦截器 */
    axios.interceptors.request.use((config) => {return config  });
    /* 响应拦截器 */
    axios.interceptors.response.use((config) => {return config  });
复制代码

这样的话loading的逻辑就可以在拦截器中实现了,具体代码看下:

    <script>
    import axios from "axios";
    export default {
      name: "Test2",
      /**
       * 数据定义
       */
      data() {
        return {
          jokeList: [],
          loading: false,
        };
      },
      /**
       * 特征函数 
       */
      methods: {
        getJokes() {
          axios
            .get("https://api.apiopen.top/getJoke?page=1&count=2&type=text")
            .then((res) => {
              this.jokeList = res.data.result;
            });
        },
      },
      created() {
        /* 请求拦截器 */
        axios.interceptors.request.use(
          (config) => {
            // 在发送请求之前做些什么
            this.loading = true;
            console.log("config", config);
            return config;
          },
          (error) => {
            console.log(error); // for debug
            return Promise.reject(error);
          }
        );
        /* 响应拦截器 */
        axios.interceptors.response.use(
          (response) => {
            this.loading = false;
            console.log("res", response);
            return response;
          },
          (er) => {
            return Promise.reject(er);
          }
        );
      },
    };
    </script>

复制代码

再看下效果:

loadings.gif 嗯,大概就是这个样子,点击然后loading,然后展示数据;现在的请求的卸载当掐你的组件内,但是工作中我们的异步请求一般都会封装好,不会每个组件写一遍,下面看看封装的过程;

axios的封装处理

1、首先编写axios的逻辑

在项目中找个地方定义一个axiosUtils.js的文件(文件名随便),实现axios的封装处理,拦截器的实现:

import axios from 'axios'
import {
  Message
} from 'element-ui'

// 创建一个axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
  timeout: 5000 // 请求超时时间
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    console.log('config', config)
    // 在发送请求之前做些什么
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)

//响应拦截器
service.interceptors.response.use(
  response => {
    console.log(response)
    const res = response.data
    // 200是自定义的状态码,根据实际情况定义
    if (res.statusCode !== 200) {
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      /* 此处还可以写一些其他的逻辑处理 */
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      return res
    }
  },
  error => {
    console.log('err' + error)
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)
export default service
复制代码

2、在定义接口的地方使用封装好的axios

    import axiosRequest from '../utils/axiosRequest';  // 引入封装好的axios实例
    /**
     * 获取实时段子
     * @param {*} data 参数
     * @returns 
     */
    export function getJokes(data) {
      return axiosRequest({
        url: 'https://api.apiopen.top/getJoke?page=1&count=2&type=text',
        method: 'post', // 请求方式 post\get\put\delete......
        data //参数
      })
    }
    /* 其他接口信息 */

    export function getInfo(token) {
      return axiosRequest({
        url: '',
        method: 'get',
        params: {
          token
        }
      })
    }

    export function logout() {
      return axiosRequest({
        url: '',
        method: 'post'
      })
    }
复制代码

3、最后一步就是在组件内使用创建好的API了

    <template>
      <div class="main">
        <el-button type="primary" size="default" @click="getJokes"
          >获取一些段子</el-button
        >
        <el-button type="primary" size="default" @click="getJokeList"
          >获取一些段子(封装)</el-button
        >
        <el-table v-loading="loading" :data="jokeList" border stripe>
          <el-table-column prop="sid" label="段子编号" width="180">
            <template slot-scope="scope">
              <el-tag type="primary" disable-transitions>{{
                scope.row.sid
              }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="name" label="标题" width="180"> </el-table-column>
          <el-table-column prop="text" label="内容"> </el-table-column>
        </el-table>
      </div>
    </template>

    <script>
    import axios from "axios";
    import { getJokes } from "../api/user";
    export default {
      name: "Test2",
      /**
       * 数据定义
       */
      data() {
        return {
          jokeList: [],
          loading: false,
        };
      },
      /**
       * 特征函数
       */
      methods: {
        getJokes() {
          // axios
          //   .get("https://api.apiopen.top/getJoke?page=1&count=2&type=text")
          //   .then((res) => {
          //     this.jokeList = res.data.result;
          //   });
        },
        getJokeList() {
          this.loading = true;
          const params = {};
          getJokes(params).then((res) => {
            if (res) {
              // TODO: 
              this.loading = false;
            }
            console.log("结果", res);
          });
        },
      },
      // created() {
      //   /* 请求拦截器 */
      //   axios.interceptors.request.use(
      //     (config) => {
      //       // 在发送请求之前做些什么
      //       this.loading = true;
      //       console.log("config", config);
      //       return config;
      //     },
      //     (error) => {
      //       console.log(error); // for debug
      //       return Promise.reject(error);
      //     }
      //   );
      //   /* 响应拦截器 */
      //   axios.interceptors.response.use(
      //     (response) => {
      //       this.loading = false;
      //       console.log("res", response);
      //       return response;
      //     },
      //     (er) => {
      //       return Promise.reject(er);
      //     }
      //   );
      // },
    };
    </script>

    <style>
    </style>
复制代码

loadingss.gif 这样的话基本就封装好了;其实在封装过程中还可以处理一些状态码的情况。

分类:
前端
标签: