1. 程式人生 > >Vue2+axios+router+loading封裝(新增圖片上傳)

Vue2+axios+router+loading封裝(新增圖片上傳)

Vue2+axios+router+loading封裝(新增圖片上傳)

vue新手,開專案一個多月了,遇到好多坑,對於喜歡每個專案的請求必須要封裝的我,這操作是必須滴;
一個要求一個要求加進入,未來還有更多要求還不知道怎麼處理,axios就是一個血淚史啊

先說說具體的要求:

  1. axios基礎封裝 :axios的基礎攔截封裝;

  2. 引數設定 :header,介面路徑、方法(get、post),引數等;

  3. 跳轉路由 :發起請求後的各種狀態下的路由跳轉(因為是封裝的,js沒有this,又不好再次引入vue\router);

  4. 進度條 :載入中、上傳中等不同的文字和樣式;

  5. axios基礎封裝跳轉路由進度條:request.js基礎程式碼

import axios from 'axios' //axios引入
import store from './store' //快取資料的名稱管理,就是localStorage的key
//引入封裝的吐司,進度條等
import {
    toast,
    LoadingBox
} from './utils'
axios.defaults.withCredentials = true; //讓ajax攜帶cookie
// const isPro = Object.is(process.env.NODE_ENV, 'production')
var lb = null; //進度條預設不顯示 var vuer = null; //vue 物件,傳遞過來的 // 建立axios例項 const service = axios.create({ //以下為代理跨域的一些baseURL,因為我們有不同的域名,暫時不用 // baseURL: process.env.BASE_API, // api的base_url // baseURL: isPro ? 'http://xxx:8041/rest/' : '/api/', // baseURL: "http://xxx:8041/rest/", timeout: 15000 // 請求超時時間 }); // request請求攔截器
service.interceptors.request.use(config => { //傳過來的vue物件(用來進行跳轉) vuer = config.that; // 讓每個請求攜帶自定義token 請根據實際情況自行修改 // if (localStorage.getItem(store.token)) { // config.headers['X-Token'] = localStorage.getItem(store.token) // } //設定header config.headers['Client-Type'] = 'WAP'; //客戶端區別 config.headers['Content-Type'] = 'application/x-www-form-urlencoded'; // config.headers['Content-Type'] = 'application/json; charset=UTF-8'; //請求的時候加入進度條(在這裡可以傳入進入條的圖示、msg(封裝時已預設載入中),還可以傳入特定的值累約束,比如:msg ==0 時,不展示) if (config.msg != 0) { lb = new LoadingBox(config.msg || ''); //展示進度條 lb.show(); } //url.js傳過來的所有引數可以統一列印 console.log("請求引數:url:" + config.url + ",data:" + config.data + ",params:" + config.params + ",method:" + config.method) return config }, error => { //網路不通,跳轉打404頁面 console.log('request跳轉404頁面:' + error) // 跳轉404頁面 vuer.$router.push({ path: '*' }) Promise.reject(error); }); // respone返回攔截器 service.interceptors.response.use( response => { //請求成功後隱藏進度條 if (lb != null) { lb.hide(); } const res = response.data if (res.result == "true") { console.log("succ:" + JSON.stringify(response.data)); // console.log(response.data); //成功後的成功返回 return res; } else { console.log("err:" + JSON.stringify(response.data)); //跳轉登入 if (res.result == "false" && res.code == "601") { //未登入 localStorage.clear(); toast(res.message); setTimeout(() => { vuer.$router.push({ name: login }) }, 500); return; } // 成功後的失敗返回 return Promise.reject(error); } }, error => { //這裡只是全域性處理不用返回 if (lb != null) { lb.hide(); } // timeout of 15000ms exceeded console.log('error跳轉404頁面:' + error) // 跳轉404頁面 if ((error == 'Error: Network Error') || (error == 'Error: timeout of 15000ms exceeded')) { //後臺伺服器未開Error: Network Error toast('連線不到伺服器') vuer.$router.push({ path: '*' }) //失敗返回 return error } } ) export default service
  1. 引數設定 :介面路徑、方法(get、post),引數等;這是url.js頁面:get post
import request from "./request";
const qs = require('qs');


let baseUrl = 'http://xxx:8041';
let baseCreditUrl = 'http://xxx:8080';

// 登入(第一個數傳來的引數,第二個是vue物件,第三個是進度條的msg,若有其他資料可以一起傳過去)

//POST
export function login(data, that,msg) {
    return request({
        url: baseUrl + "login",
        method: "post",
        data: qs.stringify(data),
        that: that,
        msg:msg
    })
}

//GET
export function login(params, that,msg) {
    return request({
        url: baseUrl + "login",
        method: "get",
        params,
        that: that,
        msg:msg
    })
}
  1. 呼叫請求
import {
  login
} from "js/url.js";
import { validatenull, toast, isMobile, promptBox } from "js/utils";
import store from "js/store";

let that = this;
let params = {name:'哈哈哈',phone:'18255556666'};
 login(params, that).then(
   response => {
   //成功後的成功處理
     if (!validatenull(response.data)) {
       toast("登入成功");
     }
   },
   error => {
    //成功後的失敗處理(如:賬戶名錯誤)
     toast(error.message);
   }
 );

至此axios封裝完成,當然還有其他要求,如跳出一個頁面就中斷請求、進度條消失等還未找到好的方法;再比如多個請求一起進行;再再比如有多個域名的代理跨域(一個域名的也沒搞定);這些還沒考慮,歡迎補充

新增圖片上傳

我的是截圖的上傳,使用的vue-cropper.js ,返回的是blob資料,然後上傳(程式碼從下往上看)
當然request.js封裝的header改改

 if (config.hds == 1) { //上傳圖片
        config.headers['Content-Type'] = 'multipart/form-data';
    } else {
        config.headers['Content-Type'] = 'application/x-www-form-urlencoded';
    }
//上傳圖片
    upload: function(file) {
      let that = this;
      let params = new FormData(); // 建立form物件
      params.append("file", file, file.name); // 通過append向form物件新增資料
      // param.append("", ""); // 新增form表單中其他資料
      console.log(params.get("file")); // FormData私有類物件,訪問不到,可以通過get判斷值是否傳進去
      // 第三個引數代表是檔案
      unploadImg(params, that, "上傳中...", 1).then(
        response => {
          // let img = this.getObjectURL(file);
          that.info['icon'] = response.data.iconUrl;
          localStorage.setItem(store.userinfo,JSON.stringify(that.info))
          toast("上傳成功");
        },
        error => {
          toast(error.message);
        }
      );
    },
    // 擷取圖片
    save: function() {
      // 獲取截圖的blob資料
      this.$refs.cropper.getCropBlob(data => {
        data.name = "head.jpg"
        this.upload(data);
      });
    },
    //選擇展示圖片
    chooseChange: function(e) {
      let file = e.target.files[0];
      let tempPath = this.getObjectURL(file);
      this.option.img = tempPath;
      //this.upload(file);//這裡是選擇上傳
    },
    //建立一個可存取到該file的url
    getObjectURL: function(file) {
      var url = null;
      if (window.createObjectURL != undefined) {
        // basic
        url = window.createObjectURL(file);
      } else if (window.URL != undefined) {
        // mozilla(firefox)
        url = window.URL.createObjectURL(file);
      } else if (window.webkitURL != undefined) {
        // webkit or chrome
        url = window.webkitURL.createObjectURL(file);
      }
      return url;
    },