下一节:

  Vue axios 封装

  • 安装

    使用npm:
    npm i axios
    使用yarn:
    yarn add axios
    使用cdn:
    <script scr="src="https://unpkg.com/axios/dist/axios.min.js""></script>
    
  • 示例

    发起一个GET请求:
    //发起一个user请求,参数为给定的ID
    axios.get('/user?ID=1234')
    .then(function(respone){
          console.log(response);
    })
    .catch(function(error){
          console.log(error);
    });
    
    //上面的请求也可选择下面的方式来写
    axios.get('/user',{
          params:{
             ID:12345
          }
    })
    .then(function(response){
       console.log(response);
    })
    .catch(function(error){
       console.log(error)
    });
    
    发起一个POST请求:
    axios.post('/user',{
       firstName:'friend',
       lastName:'Flintstone'
    })
    .then(function(response){
       console.log(response);
    })
    .catch(function(error){
       console.log(error);
    });
    
    发起一个多重并发请求:
    function getUserAccount(){
       return axios.get('/user/12345');
    }
    
    function getUserPermissions(){
       return axios.get('/user/12345/permissions');
    }
    
    axios.all([getUerAccount(),getUserPermissions()])
    .then(axios.spread(function(acc,pers){
          //两个请求现在都完成,返回一个数组
    }));
    
  • 项目应用

    http.js 中 axios 封装,先直接贴代码:
    import axios from 'axios';
    import store from '../store'  //vuex
    import {ToastError} from 'assets/js/toast.js'  //提示语,可自行封装
    axios.defaults.timeout = 5000;  //超时时间设置
    axios.defaults.withCredentials = true;  //true允许跨域
    //Content-Type 响应头
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
    
    if (process.env.NODE_ENV === 'production') {
       /*第二层if,根据.env文件中的VUE_APP_FLAG判断是生产环境还是测试环境*/
       if (process.env.VUE_APP_FLAG === 'pro') {
          //production 生产环境
          axios.defaults.baseURL = 'https://www.xxx.com';
       } else {
          //test 测试环境
          axios.defaults.baseURL = '';
       }
    } else {
       //dev 开发环境
       axios.defaults.baseURL = 'http://www.xxx1.com';
    }
    
    // 响应拦截器
    axios.interceptors.response.use(
       response => {
          // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据     
          // 否则的话抛出错误
          if (response.status === 200) {
          return Promise.resolve(response);
          } else {
          return Promise.reject(response);
          }
       },
       // 服务器状态码不是2开头的的情况
       error => {
          if (error.response.status) {
          switch (error.response.status) {
             // 401: 未登录               
             case 401:
                router.replace({
                path: '/login',
                query: {
                   redirect: router.currentRoute.fullPath
                }
                });
                break;             
             case 403:
             ToastError('管理员权限已修改请重新登录')
                // 清除sessionStorage
                store.commit("qiut")
                // 跳转登录页面,并将要浏览的页面fullPath传过去,登录成功后跳转需要访问的页面 
                setTimeout(() => {
                router.replace({
                   path: '/login',
                   query: {
                      redirect: router.currentRoute.fullPath
                   }
                });
                }, 1000);
                break;
    
             // 404请求不存在
             case 404:
             ToastError('请求页面飞到火星去了')
                break;
          }
          return Promise.reject(error.response);
          }
       });
    
    
    
    /**
       * 封装get方法
       * @param url
       * @param data
       * @returns {Promise}
       */
    
    export function get(url, params = {}) {
       return new Promise((resolve, reject) => {
          axios.get(url, {
             params: params
          })
          .then(response => {
             resolve(response.data);
          })
          .catch(err => {
             reject(err)
          })
       })
    }
    
    
    /**
       * 封装post请求
       * @param url
       * @param data
       * @returns {Promise}
       */
    
    export function post(url, data = {}) {
       return new Promise((resolve, reject) => {
          axios.post(url, data)
          .then(response => {
             resolve(response.data);
          }, err => {
             reject(err)
          })
       })
    }
    
    /**
       * 封装delete请求
       * @param url
       * @param data
       * @returns {Promise}
       */
    
    export function deletes(url, data = {}) {
       return new Promise((resolve, reject) => {
          axios.delete(url, data)
          .then(response => {
             resolve(response.data);
          }, err => {
             reject(err)
          })
       })
    }
    
    /**
       * 封装put请求
       * @param url
       * @param data
       * @returns {Promise}
       */
    
    export function put(url, data = {}) {
       return new Promise((resolve, reject) => {
          axios.put(url, data)
          .then(response => {
             resolve(response.data);
          }, err => {
             reject(err)
          })
       })
    }  
    
    这里新建了一个api文件夹,里面有一个index.js来管理接口
    //引用上面的http.js文件
    import {get, post, put, deletes} from './http'
    //登录接口
    export const getLogin = (fromData)=> post('user/login',fromData)
    //退出登录接口
    export const getLoginOut = ()=> get('user/logout')
    //图片上传接口 参数 ${type},fileData
    export const SaveImg = (type,fileData)=> post(`goods/save_img/${type}`,fileData)
    
    在登录页 login.vue 中应用 axios 的封装:
    <template>
    <div class="login-big-bg">
       <div class="login-content-box">
             <div class="login-box">
                <el-alert :title="errorTip" :closable="false" v-show="errorTip" type="error" show-icon></el-alert>
                <div class="label-item">
                   <i class="user-icon"></i>
                   <input @keyup.enter="Login" class="input" type="text" placeholder="请输入用户名" v-model.trim="loginForm.username" />
                </div>
                <div class="label-item">
                   <i class="password-icon"></i>
                   <input @keyup.enter="Login" class="input" type="password" placeholder="请输入密码" v-model.trim="loginForm.password" />
                </div>
                <el-button type="primary" class="login-btn" @click="Login()">登录</el-button>
             </div>
       </div>
    </div>
    </template>
    
    <script>
    import qs from "qs"; // qs库可以表单序列化提交
    import { Message } from "element-ui"; //vue element-ui 框架
    import { getLogin } from "api";  // 调用api 登录接口
    export default {
       name: "login",
       data() {
          return {
          loginForm: {
             username: "",
             password: ""
          },
          errorTip: ""
          };
       },
       methods: {
          Login() {
             if (this.loginForm.username === "") {
                this.errorTip = "账号不能为空";
             } else if (this.loginForm.password === "") {
                this.errorTip = "密码不能为空";
             } else {
                let fromData = decodeURI(qs.stringify(this.loginForm));
                getLogin(fromData)
                .then(res => {
                   if (res.success) {
                      this.$store.commit("login", res.data); //把登录返回的数据存在vuex里
                      this.$router.push("/goods/add");  //登录成功后跳转页面
                      this.loginForm.username='';
                      this.loginForm.password='';
                   } else {
                      this.errorTip = res.data.msg;
                   }
                })
                .catch(error => {
                   this.errorTip = error;
                });
             }
          }
       }
    };
    </script>
    <style lang="less" scoped>
    //....写自己的样式
    </style>
    
下一节: