在使用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