在使用vue技術棧開發各種管理系統時,常常須要相同的開發目錄架設。在平常開發中,整理了一套本身的開發目錄。主要包括
vuejs
、vue-router
、vuex
、axios
等經常使用類庫。javascript
"vuex": "^3.1.0",
"babel-polyfill": "^6.26.0",
"element-ui": "^2.9.1",
"vue": "^2.5.2",
"vue-router": "^3.0.1",
"axios": "^0.18.0",
複製代碼
vue-templatecss
vue-template
主要使用axios
作請求處理,在src/api/index.js
中對axios
作了二次封裝,而後把封裝函數gl_ajax
掛載在全局vue.prototype
上,經過各層嵌套組件經過原型能夠獲取gl_ajax
函數。在router/index.js
主要是路由定義和路由導航守衛功能。詳細狀況能夠參考提供源碼地址。vue
|-- App.vue(掛載根組件)
|-- api(封裝請求相關模塊)
| |-- api.js(公用api接口定義)
| |-- config.js(項目請求地址和其餘參數)
| |-- index.js(axios二次封裝定義)
|-- components(公用業務組件)
|-- main.js(程序執行入口)
|-- plugins(開發vue插件目錄)
| |-- el_icon(Icon組件)
| | |-- Icon.vue
| | |-- assets
| | | |-- error.svg
| | | |-- info.svg
| | | |-- success.svg
| | | |-- warning.svg
| | |-- index.js
| |-- el_message(message提示組件)
| |-- index.js
| |-- main.js
| |-- message.vue
|-- router(路由定義和路由守衛)
| |-- index.js
|-- store(vuex定義和action)
| |-- index.js
| |-- types.js
|-- views(業務組件)
|-- Home.vue
|-- Login.vue
|-- index.vue
複製代碼
main
入口main
入口對類庫進行掛載,二次封裝的函數gl_ajax
、第三方組件庫elementui
。vue
官方提議對掛載在vue
原型鏈上的自定義函數加前綴$
區分,這裏使用alias:$gl_ajax
來進行掛載。java
import Vue from "vue";
import "babel-polyfill";
import App from "./App";
import router from "./router";
import store from "./store/index.js";
import { gl_ajax } from "./api/index.js";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
Vue.prototype.$gl_ajax = gl_ajax;
Vue.config.productionTip = false;
Vue.use(ElementUI);
new Vue({
el: "#app",
store,
router,
components: { App },
template: "<App/>"
});
複製代碼
開發後臺管理系統,某些頁面須要對用戶或遊客進行權限驗證。因此在路由文件添加路由守衛,阻止未登陸用戶對需權限的頁面的操做。ios
在使用vue
中採起先後端分離的形式,經過JWT
獲取對api
接口的請求權限token
,在登陸中獲取token
,而後保存在sessionStorage
中,之因此不把token
保存在vuex
中,是由於瀏覽器刷新會致使store
數據重置。失去登陸token
。這裏採用的是sessionStorage
加vuex
的形式,避免了上述的弊端。git
// 頁面刷新時,從新賦值token
if (window.sessionStorage.getItem("token")) {
store.commit(types.LOGIN, window.sessionStorage.getItem("token"));
}
複製代碼
下面是router/index.js
的完整定義源碼github
import Vue from "vue";
import VueRouter from "vue-router";
import store from "../store/index";
import * as types from "../store/types";
Vue.use(VueRouter);
const routes = [{
path: '',
redirect: '/login'
}, {
path: "/",
component: resolve => require(["@/views/Home"], resolve),
children: [{
path: '/admin',
name: 'admin',
component: resolve => require(["@/views/index"], resolve)
}]
},
{
path: "/login",
name: "Login",
component: resolve => require(["@/views/Login"], resolve)
}
];
// 頁面刷新時,從新賦值token
if (window.sessionStorage.getItem("token")) {
store.commit(types.LOGIN, window.sessionStorage.getItem("token"));
}
const router = new VueRouter({
mode: "history",
routes
});
//路由導航守衛
router.beforeEach((to, from, next) => {
if (to.path == "/login") {
store.commit(types.LOGOUT);
next();
} else {
const token = sessionStorage.getItem("token");
if (!token) {
next({
path: "/login",
query: {
redirect: to.fullPath
}
});
} else {
next();
}
}
});
export default router;
複製代碼
vuex
在路由導航中,使用store
加sessionStorage
形式保存登陸token
,在store/index.js
中也定義了登陸和退出操做mutations
。ajax
把退出操做定義在store
中,是爲了下面對登陸權限過時,返回401
狀態碼,進行重定向操做功能。vue-router
import Vue from "vue";
import Vuex from "vuex";
import * as types from "./types";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
token: null
},
mutations: {
[types.LOGOUT]: (state, data) => {
sessionStorage.removeItem("token");
state.token = null;
},
[types.LOGIN]: (state, data) => {
sessionStorage.setItem("token", data);
state.token = data;
}
},
actions: {},
getters: {}
});
複製代碼
axios
封裝api/index.js
文件中對axios
進行了二次封裝。同一根目錄下config.js
定義請求超時時間、開發和線上請求URL
。vuex
axios
請求攔截對axios
請求錯誤攔截是重點部分。主要對權限過時401
和請求超時操做store
對保存的token
清除,而後再對路由進行重定向。
axios.interceptors.response.use(
response => {
return response;
},
error => {
if (error.response) {
switch (error.response.status) {
case 401:
store.commit(types.LOGOUT);
router.replace({
path: "/login",
query: {
redirect: router.currentRoute.path
}
});
}
const message = error.response.data.message ?:'未知錯誤';
Message.error(message);
} else if (error.code == 'ECONNABORTED' && error.message.indexOf('timeout') != -1) {
Message.error("請求已超時");
}
return Promise.reject(error);
}
);
複製代碼
gl_ajax
請求封裝responseType
是axios
請求文件下載須要的接受類型,文件是經過application/json
方式進行獲取。
export const gl_ajax = params => {
return axios({
method: params.method.toLowerCase(),
url: `${axios.defaults.baseURL}${params.url}`,
data: params.method != "get" ? params.data : "",
params: params.method == "get" ? params.data : "",
responseType: params.file ? "blob" : ""
})
.then(res => {
params.success && params.success(res);
})
.catch(err => {
params.error && params.error(err);
});
};
複製代碼
gl_ajax
使用在vue
的原型上定義了$gl_ajax
函數,在login
常見登陸中須要請求接口獲取token
權限,下面對$gl_ajax
介紹使用方式和對token
保存操做。
self.$store.commit(types.LOGIN,token)
在vuex
中保存token
,會在sessionStorage
和store
分別保存一份token
值。防止瀏覽器刷新形成vuex
中token
丟失。
<template>
<div>
<button @click='loginSystem'>login</button>
</div>
</template>
<script>
import * as types from "../store/types.js";
export default {
name: "Login",
data() {
return {};
},
methods: {
loginSystem() {
const self = this;
this.$gl_ajax({
url: "/login",
method: "post",
data: { ...self.loginData },
success(res) {
if (res.data.status == "ok") {
const token = res.data.jwt;
self.$store.commit(types.LOGIN, token);
self.message("login success");
self.$router.push({
path: "/admin"
});
}
},
error(err) {}
});
}
}
};
</script>
<style>
</style>
複製代碼
若是以爲有幫助,能夠給個贊~或star~呀
github地址:vue-template