需求由來: 當項目愈來愈大的時候提升項目運行編譯速度、壓縮代碼體積、項目維護、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 // 測試目錄
/** * 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 }
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 }
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, };
<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>
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'
<script> import prompt from '@/services/prompt' export default { name: 'app', mounted() { // 全局錯誤初始化 prompt.init.call(this) } } </script>
以上就是pc端的項目配置化、請求統一管理內容了。有疑問的地方留言看到後會第一時間回覆,或可改進的地方歡迎指導, 下面介紹vuex管理版本。vuex
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
this.$store.dispatch(`${storeName}/getApplicent`) .then((data) => { console.log(data) })
這就能夠啦。vue-cli
本文爲原創 轉載請註明出處 。npm