準備工作
需求由來: 當項目越來越大的時候提高項目運行編譯速度、壓縮代碼體積、項目維護、bug修復......等等成為不得不考慮而且不得不做的問題。
?又或者后面其他同事接手你的模塊,或者改你的bug時避免人家看的眼痛以及心里千百句mamaipi...問候。
并且一個好的開發思路也能大大提高開發效率,以及檢驗自己。
進入正題:
在本地用?vue-cli?
新建一個項目,這個步驟vue的官網上有,我就不再說了。
這里展示一下我的項目架構目錄? 這次主要講紅字具體實現部分
├── 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/234845axios.interceptors.request.use(function (config) {// 為所有接口加上前綴 例 https://www.kancloud.cn/yunye/axios/234845 前綴為 https://www.kancloud.cn// 因為相同環境下的所有接口前綴肯定是一樣的 window.localStorage.gatewayDomain 為前綴域名 倘若后面更改域名之類的 只需改一個地方就行了 就不用說每個調接口的地方都去改 維護便捷// 若想了解分環境打包以及分環境設置 公共域名、前綴等 請看以往博文 https://www.cnblogs.com/ljx20180807/p/9456489.htmlconfig.url = window.localStorage.gatewayDomain + config.url// 登錄時設置 cookiesvar cookies = globalConfig.getCookies()if (config.url.indexOf('?') < 0) {config.url += '?'}// 為所有接口加上 access_tokenconfig.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 狀態200if (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 codeif (!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 統一管理請求 stroe/actions.js文件
import Vue from 'vue'// 全局域名 const apiUrlBase = window.apiUrlBaseconst 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)})
這就可以啦。
本文為原創 轉載請注明出處 。
?