Vue + webpack 項目配置化、接口請求統一管理

準備工做

需求由來: 當項目愈來愈大的時候提升項目運行編譯速度、壓縮代碼體積、項目維護、bug修復......等等成爲不得不考慮並且不得不作的問題。css

      又或者後面其餘同事接手你的模塊,或者改你的bug時避免人家看的眼痛以及內心千百句mamaipi...問候。html

      而且一個好的開發思路也能大大提升開發效率,以及檢驗本身。vue

進入正題:ios

在本地用 vue-cli 新建一個項目,這個步驟vue的官網上有,我就再也不說了。es6

這裏展現一下個人項目架構目錄  此次主要講紅字具體實現部分ajax

      ├── build                       // 項目build腳本
      ├── config                      // 項目配置目錄
      ├── dist                        // 項目輸出部署目錄,執行 npm run build後生成
      ├── src                         // 生產目錄
      │   ├── assets                  // 靜態資源,包含圖片等
      │   ├── components              // 項目公用組件,例如Header、Footer組件等
      │   ├── mock                    // 接口mock文件目錄
      │       └── index.js            // mock接口集合文件
      │   ├── pages                   // 頁面目錄
      │   │   ├── Demo                // Demo模塊,必須用大寫開頭
      │   │   │   ├── components      // Demo模塊專用組件 組件建議所有首字母大寫
      │   │   │   ├── style           // Demo模塊專用css
      │   │   │   ├── services        // Demo模塊服務,能夠包含相應方法類
      │   │   │   ├── interface.js    // Demo模塊接口結合文件
      │   │   │   └── index.vue       // Demo模塊頁面入口
      │   │   └── Other               // 其餘頁面目錄
      │   ├── router                  // 路由配置文件,若是路由太多了,能夠拆分
      │   ├── services                // 項目公用配置服務
      │   │   │   ├── ajax.js         // 全部接口請求公共配置   能夠和 request.js 合併一塊兒 不嫌代碼太長的話
      │   │   │   ├── request.js      // (需求有則添加) 爲全部接口設置公共請求頭
      │   │   │   ├── prompt.js       // 全局的提示  例如:接口錯誤提示、保存成功提示、操做錯誤提示等等...
      │   │   │   ├── validate.js     // 全局表單校驗具體封裝可參照element-ui form表單模塊
      │   ├── App.vue                 // 組件入口
      │   ├── config.js               // 項目配置文件  例如:權限校驗,cookie設置、access_token獲取等等...
      │   ├── interface.js            // 項目公共接口文件
      │   └── main.js                 // Webpack 預編譯主入口
      ├── style                       // 項目公用style
      ├── static                      // 靜態文件目錄,保留
      │   └── i18n                    // 國際化目錄,每個目錄爲一種語言
      │       ├── zh                  // 中文目錄
      │       │   └── index.json      // 配置文件
      │       └── en                  // 英文目錄
      ├── index.html                  // 項目入口文件,通常不用改動
      ├── package.json                // 項目配置
      ├── README.md                   // 項目說明
      ├── CHANGE_LOG.md               // 項目更新歷史文檔
      └── test                        // 測試目錄

services/aiax.js文件

/**
 * ajax 模塊,能夠將 axios 替換成 $.ajax 等
 */ import axios from 'axios';
import globalConfig from '../config' import { Notification } from 'element-ui'

// 注: 具體設置具體判斷 根據公司項目需求 以及 接口需求   如今以我公司爲例

const init = function () {
  // 添加 axios 請求攔截器爲全部請求加上前綴 、 access_token  (我公司全部接口都比要有 access_token才能訪問)
  // 有對 axios 不是很瞭解的 能夠看看 axios 官方文檔  https://www.kancloud.cn/yunye/axios/234845
  axios.interceptors.request.use(function (config) {
    // 爲全部接口加上前綴 例 https://www.kancloud.cn/yunye/axios/234845 前綴爲 https://www.kancloud.cn
    // 由於相同環境下的全部接口前綴確定是同樣的 window.localStorage.gatewayDomain 爲前綴域名  假若後面更改域名之類的  只需改一個地方就好了 就不用說每一個調接口的地方都去改  維護便捷
    // 若想了解分環境打包以及分環境設置 公共域名、前綴等  請看以往博文 http://www.javashuo.com/article/p-ojoqppxm-hn.html
    config.url = window.localStorage.gatewayDomain + config.url
    
    // 登陸時設置 cookies
    var cookies = globalConfig.getCookies() if (config.url.indexOf('?') < 0) {
      config.url += '?'
    }
    // 爲全部接口加上 access_token
    config.url += ('access_token=' + cookies['access_token'])
    if (!config.data) config.data = {}
    return config;
  }, function (err) {
    // 錯誤處理
    return Promise.reject(err)
  })

  // 添加 axios 響應攔截器
  axios.interceptors.response.use(function (response) {

    // 這裏是當接口請求服務器成功響應的狀況   解構賦值出須要的數據
    const {status, data} = response;

    if (status === 200) {
      // 若是不出現錯誤,直接向回調函數內輸出 data  狀態200
      if (data.error === 'SUCCESS') {
        // 成功不用提示
        return data
      } else {
        // 若出現錯誤則彈窗錯誤提示
        if (data.message) {
          Notification({
            title: '錯誤',
            message: data.message,
            type: 'error',
            customClass: 'el-error-msg',
            duration: 2000
          })
        }
        return data
      }
    } else {
      return response;
    }
  }, function (error) {
    // 這裏是當接口請求失敗的狀況 (例如服務器沒響應、後臺代碼問題之類的)  (具體的響應判斷根據你後臺返回狀態碼結構)
    const {response} = error;

    // 這裏處理錯誤的 http code
    if (!response || response.status === 404) {
      if (!response) {  // access_token 失效的狀況 彈窗提示
 Notification({
          title: '錯誤',
          message: 'access_token已失效請從新登陸',
          type: 'error',
          customClass: 'el-error-msg',
          duration: 1500,
          onClose() {
            window.location.href = window.localStorage.loginUrl  // 自動跳轉返回登陸頁從新獲取access_token
          }
        })
      } else {
        // 這是請求url不對的狀況
        console.log('404 error %o' + error);
      }
    }
    // Do something with response error 對響應錯誤作點什麼
    return Promise.reject(error.message);
  });
};

export default {
  init
}

services/prompt.js文件

const init = function () {
  const _this = this;
  // 建議爲了方便使用,這裏能夠包裝window.Alert  具體怎麼使用往下看
  window.Alert = function (msg, duration = 3000) {
    // 錯誤提示
 _this.$notify({
      title: '錯誤',
      message: msg,
      type: 'error',
      customClass: 'el-error-msg',
      duration
    });
  }
 // 成功提示
  window.Tips = function (msg, duration = 3000) {
    _this.$notify({
      title: '成功',
      message: msg,
      type: 'success',
      duration
    });
  }
 // 警告提示
  window.Warning = function (msg, duration = 3000) {
    _this.$notify({
      title: '警告',
      message: msg,
      type: 'warning',
      duration
    });
  }

  // 全局延時器
  window.SetTimeout = function (path, queryObject) {
    setTimeout(_ => {
      _this.$router.push({
        path: path,
        query: queryObject
      });
    }, 500)
  }
};

export default {
  init
}

page/Demo/interface.js文件  (pc端不建議用vuex  具體看需求吧   vuex管理版本 往下看)

import axios from 'axios';

const ajax = {
  // 獲取影像件上傳列表
  GET_IMAGE_LIST: 'images?'
};
// 提取公共部分
const API_PATH_PRE_FIX = 'apply/v1/'; 

// 增長接口模塊前綴
let INTERFACE = {};
for (let key in ajax) {
  INTERFACE[key] = API_PATH_PRE_FIX + ajax[key];
}

/**
 * 方式1: 多參數狀況  獲取列表
 * @param data 參數
 * @returns {*}
 */
function getImageList(data) {
  return axios.get(INTERFACE.GET_IMAGE_LIST, {
    params: data
  }).catch(function (error) {
    window.Alert(error);
  });
}

/**
 * 方式2: es6模板語法  獲取基本信息
 * @param data 參數
 * @returns {*}
 */
function getContrantInfo(API_PATH_PRE_FIX, agreementId) {
  return axios.get(`${API_PATH_PRE_FIX}/middle/agreement/basic?agreementId=${agreementId}&`).catch(function (error) {
    window.Alert(error);
  });
}
export default {
  getImageList,
  getContrantInfo,
};

page/Demo/index.vue文件

<script>
// 引入上面的接口文件 import INTERFACE from './interface' export default { data() { return { imageList: [], deleteList: [] } }, created() { // 獲取列表 (調用封裝好的請求) INTERFACE.getImageList().then(data => { if (data && data.data) this.imageList = data.data }) }, methods: { // 確認刪除 handleDelete() { INTERFACE.deleteAgreement(this.deleteList).then(data => { // 操做成功提示 (上面定義好的全局提示) window.Tips('刪除成功!') }) } } } </script>

src/main.js文件

import Vue from 'vue' import ElementUI from 'element-ui' import App from './App' import ajax from '@/services/ajax'

// axios 統一配置
ajax.init()

// 全局變量
indow.localStorage.gatewayDomain = 'https://dev-api.cn/'
window.localStorage.defaultLanguage = 'ZH_CN'

src/App.vue文件

<script> import prompt from '@/services/prompt'
export default {
  name: 'app',
  mounted() {
    // 全局錯誤初始化
    prompt.init.call(this)
  }
}
</script>

以上就是pc端的項目配置化、請求統一管理內容了。有疑問的地方留言看到後會第一時間回覆,或可改進的地方歡迎指導, 下面介紹vuex管理版本。vuex

移動端結合Vuex 統一管理請求 stroe/actions.js文件

import Vue from 'vue'

// 全局域名
const apiUrlBase = window.apiUrlBase

const API_URL = {
  GET_APPLICENT: `${apiUrlBase}/app/v1/apply/dictionaries`
}

const actions = {
   /**
 * 獲取投保人數據字典
 */
actions.getApplicent = ({ state }) => {
  return new Promise((resolve, reject) => {
    Vue.http.get(`${API_URL.GET_APPLICENT}?access_token=${state.accessToken}`).then((ret) => {
        resolve(ret.body)
      }).catch((err) => {
        reject(err)
      })
    })
  }
}

export default actions

.vue文件裏調用

this.$store.dispatch(`${storeName}/getApplicent`)
      .then((data) => {
        console.log(data)
      })

這就能夠啦。vue-cli

本文爲原創 轉載請註明出處 。npm

相關文章
相關標籤/搜索