1.config index.js下面的跨域代理設置:
proxyTable: {
'/api': {
target: 'http://xxxx', //要訪問的后端接口
changeOrigin: true,
pathRewrite: {
'^/api': 'http://xxx'
}
},
},
2.http.js(封裝axios)
import Vue from 'vue'
import axios from 'axios'
import QS from 'qs' //視情況用於不用;
import { Loading, Message } from 'element-ui';
import store from '../store/index'
let loading //定義loading變量
function startLoading() { //使用Element loading-start 方法
loading = Loading.service({
lock: true,
text: '努力加載中……',
background: 'rgba(0, 0, 0, 0.5)'
})
}
function endLoading() { //使用Element loading-close 方法
loading.close()
}
//那么 showFullScreenLoading() tryHideFullScreenLoading() 要干的事兒就是將同一時刻的請求合並。
//聲明一個變量 needLoadingRequestCount,每次調用showFullScreenLoading方法 needLoadingRequestCount + 1。
//調用tryHideFullScreenLoading()方法,needLoadingRequestCount - 1。needLoadingRequestCount為 0 時,結束 loading。
let needLoadingRequestCount = 0
export function showFullScreenLoading() {
if (needLoadingRequestCount === 0) {
startLoading()
}
needLoadingRequestCount++
}
export function tryHideFullScreenLoading() {
if (needLoadingRequestCount <= 0) return
needLoadingRequestCount--
if (needLoadingRequestCount === 0) {
endLoading()
}
}
let baseWebURL = '';
// 環境的切換
if (process.env.NODE_ENV == 'development') { //開發環境
baseWebURL = '/api' + '/api';(多加一個api是后台那邊統一攔截處理視項目情況而定加不加)
} else if (process.env.NODE_ENV == 'test') { //測試環境
baseWebURL = 'https://www.test.com';
} else if (process.env.NODE_ENV == 'production') { //生產環境
baseWebURL = 'http://www.producetion.com';
}
//生成一個axios實例
var instance = axios.create({
baseURL: baseWebURL,
});
console.log(instance, 'instance')
//1.請求超時時間
instance.defaults.timeout = 10000;
//2.post請求頭
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
//3.公共部分(請求帶token設置)
//instance.defaults.headers.common['Authorization'] = store.state.token;
//4.返回數據類型的定義
//instance.defaults.responseType = 'json';
//5.帶cookie請求
instance.defaults.withCredentials = true
// 請求攔截器
instance.interceptors.request.use(
config => {
console.log(config, 'config請求攔截器')
//1.全局loadin配置
/*2.token校驗:一般是在登錄完成之后,將用戶的token通過localStorage或者cookie存在本地;
然后用戶每次在進入頁面的時候(即在main.js中),會首先從本地存儲中讀取token;
如果token存在說明用戶已經登陸過則更新vuex中的token狀態;
然后,在每次請求接口的時候,都會在請求的header中攜帶token;
后台人員就可以根據你攜帶的token來判斷你的登錄是否過期,如果沒有攜帶,則說明沒有登錄過。
v1.每次發送請求之前判斷vuex中是否存在token
v2.如果存在,則統一在http請求的header都加上token,這樣后台根據token判斷你的登錄情況
v3.即使本地存在token,也有可能token是過期的,所以在響應攔截器中要對返回狀態進行判斷*/
const token = store.state.token;
alert(token,'token')
token && (config.headers.Authorization = token);
if (config.method == 'post') {
console.log('post請求統一需要做什么判斷')
}
//config.headers.Accept = 'application/json'; //規定接受形式json格式
showFullScreenLoading() //開啟loading
return config;
}, error => {
return Promise.reject(error);
});
// 響應攔截器
instance.interceptors.response.use(
response => {
console.log(response, 'response響應攔截器')
// 如果返回的狀態碼為200,說明接口請求成功,可以正常拿到數據
//否則的話拋出錯誤
if (response.status === 200) {
tryHideFullScreenLoading() //關閉loading
Message({
showClose: true,
message: '響應成功',
type: 'success'
})
return Promise.resolve(response);
} else {
return Promise.reject(response);
}
}, error => {
console.log(error, 'error')
if (error.response.data.status) {
console.log('后台錯誤碼統一處理')
switch (error.response.data.status) {
// 401:未登錄;未登錄則跳轉登錄頁面,並攜帶當前頁面的路徑;在登錄成功后返回當前頁面,這一步需要在登錄頁操作。
case 401:
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
break;
// 403:token過期;登錄過期對用戶進行提示;清除本地token和清空vuex中token對象;跳轉登錄頁面
case 403:
Message({
showClose: true,
message: '登錄過期,請重新登錄',
duration: 1000,
type: 'warning'
})
//清除token
localStorage.removeItem('userToken');
store.commit('LOGIN_OUT', null);
//跳轉登錄頁面,並將要瀏覽的頁面fullPath傳過去,登錄成功后跳轉需要訪問的頁面
setTimeout(() => {
router.replace({
path: '/login',
query: {
redirect: router.currentRoute.fullPath
}
});
}, 1000);
break;
//404請求不存在
case 404:
Message({
showClose: true,
message: '網絡請求不存在',
duration: 1000,
type: 'error'
})
break;
//其他錯誤,直接拋出錯誤提示
default:
Message({
showClose: true,
message: error.response.data.message,
duration: 1000,
type: 'error'
})
}
}
return Promise.reject(error);
});
// 封裝axios的get請求
export function getData(url, params) {
return new Promise((resolve, reject) => {
instance.get(url, params).then(response => {
resolve(response.data);
})
.catch(error => {
reject(error);
});
});
}
// 封裝axios的post請求
export function postData(url, params) {
return new Promise((resolve, reject) => {
instance.post(url, QS.stringify(params)).then(response => {
resolve(response.data);
})
.catch(error => {
reject(error);
});
});
}
3.api.js(封裝接口)
import { postData, getData } from './http.js'
export function cityList(data = {}) {
return postData('/xxxx/xx', data);
}
4.vuex構成
(1)index.js
import Vue from 'vue';
import Vuex from 'vuex';
import state from './state'
import mutations from './mutations'
import getters from './getters'
import actions from './actions'
Vue.use(Vuex);
const store = new Vuex.Store({
state,
mutations,
getters,
actions
});
export default store;
(2)state.js
export default {
state: {
// 存儲token
token: localStorage.getItem('userToken') ? localStorage.getItem('userToken') : ''
}
}
(3)mutation-types.js (常量)
export const LOGIN_IN = 'LOGIN_IN';//登入 export const LOGIN_OUT = 'LOGIN_OUT';//登出
(4)mutation.js
import * as type from './mutation-types'
export default {
//登入
[type.LOGIN_IN](state, token) {
state.token = token;
localStorage.setItem('userToken', token);
},
//登出 or 退出登入
[type.LOGIN_OUT](state, token) {
localStorage.removeItem("userToken", token);
state.token = token;
},
}
(5)actions (這里是異步操作)
export default{
//actions這里提交的是mutation
getLoginInInfo({commit},token){
commit('LOGIN_IN',token)
},
getLoginOutInfo({commit},token){
commit('LOGIN_OUT',token)
}
}
(6)getters.js 視情況放什么獲取state更改后的值
(7)路由 router下面的index.js
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store/index'
//方式一:最簡單直接的使用組件
//import HelloWorld from '@/components/HelloWorld'
//import Test from '@/components/test'
//方式二:webpack自帶的模塊按需加載 r就是resolve
//const HelloWorld = r => require.ensure([], () => r(require('@/components/HelloWorld')), 'HelloWorld');
Vue.use(Router)
const router = new Router({
mode: 'history', //去掉地址欄#號
routes: [{
path: '/',
name: 'testMain',
meta: {
title: '系統首頁',
requireAuth: true, // 添加該字段,表示進入這個路由是需要登錄的
},
component: resolve => require(['@/components/testMain'], resolve) //測試首頁
}, {
path: '/login',
name: 'login',
meta: {
title: '登入',
},
component: resolve => require(['@/components/login'], resolve) //模擬登入------(方式三:懶加載方式)
}, {
path: '/HelloWorld',
name: 'HelloWorld',
meta: {
requireAuth: true,
title: '測試二級聯動路由傳參',
},
component: resolve => require(['@/components/HelloWorld'], resolve) //測試二級聯動路由傳參
}, {
path: '/test',
name: 'test',
meta: {
requireAuth: true,
title: '測試參數解碼',
},
component: resolve => require(['@/components/test'], resolve) //測試參數解碼
}, {
path: '/testEgdit',
name: 'testEgdit',
meta: {
requireAuth: true,
title: '富文本編輯器試用',
},
component: resolve => require(['@/components/testEgdit'], resolve) //富文本編輯器試用
}, {
path: '/testElementComponent',
name: 'testElementComponent',
meta: {
requireAuth: true,
title: 'element ui組件測試',
},
component: resolve => require(['@/components/testElementComponent'], resolve) //element ui 組件測試
}, {
path: '/tableTest',
name: 'tableTest',
meta: {
requireAuth: true,
title: 'element ui表格組件測試',
},
component: resolve => require(['@/components/tableTest'], resolve) //element ui table組件測試
}, {
path: '/echartTest',
name: 'echartTest',
meta: {
requireAuth: true,
title: 'echart插件測試',
},
component: resolve => require(['@/components/echartTest'], resolve) //echart插件測試
}, {
path: '*',
name: 'notFound',
meta: {
title: '404頁面',
},
component: resolve => require(['@/components/notFound'], resolve) //全不匹配的情況下,返回404,路由按順序從上到下,依次匹配。最后一個*能匹配全部
}]
})
router.beforeEach((to, from, next) => {
//可以做 loadong 開始加載 效果
store.state.token = localStorage.getItem('userToken'); //獲取本地存儲的token
if (to.meta.title) { //判斷是否有標題 該操作可以再監聽路由時候處理 watch:{'$route'(to,from){xxx操作}}
document.title = to.meta.title
}
if (to.meta.requireAuth) { // 判斷該路由是否需要登錄權限
if (store.state.token) { // 通過vuex state獲取當前的token是否存
console.log('有token時候', to, from, next)
next();
} else {
console.log('沒有token時候', to)
next({
path: '/login',
query: { redirect: to.fullPath } // 將跳轉的路由path作為參數,登錄成功后跳轉到該路由
})
}
} else {
next();
}
})
router.afterEach(route => {
//loading加載完成
});
export default router;

