本文是vue技术栈基础架子包含:
1 路由配置
2 vuex使用模块化
3 axios封装
4 element-ui 组件库
5 其他 moment 日期格式化 vuex-persistedstate 解决刷新vuex数据丢失。
目录
微信图片_20190612144350.png
main.js 入口
import Vue from 'vue'
import App from './App'
import 'element-ui/lib/theme-chalk/index.css';
import ElementUI from 'element-ui';
import store from './store' // vuex 中文地址 https://vuex.vuejs.org/zh/guide/
import router from './router' // vue-router 中文地址 https://router.vuejs.org/zh/
import plug from './plug' // 插件 全局指令、方法等
Vue.use(ElementUI);
Vue.use(plug);
Vue.config.productionTip = false;
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store,
components: { App },
template: '<App/>'
})
router/index.js 路由配置
import Vue from 'vue'
import Router from 'vue-router'
import store from '../store'
Vue.use(Router)
const router = new Router({
mode: 'history', // 路由模式 history模式,发布服务器需要后端配合。参考地址 https://router.vuejs.org/zh/guide/essentials/history-mode.html
routes: [
{
path: '/',
name: 'home',
component:() => import('@/views/home/home'),
meta: {
title: '首页'
}
}
]
})
// vue-router 全局前置守卫
router.beforeEach((to,from,next)=>{
// token
let token = store.state.common.userInfo.token;
// 设置网页标题
if(to.meta.title) {
document.title = to.meta.title;
}
// 判断token是否存在
if(token) {
next(); // 正常跳转
} else { // 跳转 登录页面
if(to.path == "/login") {
next();
} else {
next("/login");
}
}
});
export default router
store/index.js vuex
import Vue from 'vue'
import Vuex from 'vuex'
import createPersistedState from "vuex-persistedstate" // 解决刷新,vuex数据丢失
import common from './modules/common'// 公共的
Vue.use(Vuex)
const store = new Vuex.Store({
// 解决F5刷新页面vuex数据丢失问题
plugins: [createPersistedState({
storage: window.localStorage
})],
modules: { // vuex 模块化
common
}
})
export default store
store/modules/common.js 公共的
const common = {
state: {
userInfo: {
token: 'token'
}, // 用户信息
},
getters: {
},
actions: {
// 保存用户信息
setUserInfo:({commit},userInfo) => {
commit('SETUSERINFO',userInfo);
}
},
mutations: {
SETUSERINFO: (state, userInfo) => {
state.userInfo = userInfo;
}
}
}
export default common
api/index.js axios数据交互处理
import {Message, Loading } from 'element-ui'
import axios from 'axios' // axios 中文说明 https://www.kancloud.cn/yunye/axios/234845
import store from '@/store'
import router from '@/router'
let loading = null; // 请求 loading
// token 过期 清除 vuex 用户信息 清除本地缓存
let invalidToken = () => {
Message({
message:"登录过期,请重新登录",
type:'error',
duration:3000,
showClose: true,
})
//清空 token 和 用户信息
store.dispatch('setUserInfo', {})
// 清空所有缓存
window.localStorage.clear();
// 跳转登录页面
router.push({
name: 'login'
})
}
// 动态配置 axios baseURL 根据当前url地址,配置 api 接口。 生产或测试
let baseURL = window.location.href.indexOf('生产环境域名') !== -1 ? '生产api地址' : '测试api地址';
// 创建实例
const service = axios.create({
baseURL: '', // 请求api地址
timeout: 30000, // 超时时间 毫秒
withCredentials: true // 表示跨域请求时是否需要使用凭证
})
// 添加请求拦截器
service.interceptors.request.use(
config => {
// loading open
loading = Loading.service({
lock: true,
text: '努力加载中...',
background: 'rgba(0,0,0,0.7)',
target: document.querySelector('.loading-area') // 设置加载动画区域
});
// vuex 用户信息 token
let token = store.state.common.userInfo.token;
// 添加请求头
if (token) {
config.headers.Authorization = token;
}
return config
},
error => {
loading.close();
Message({
message:'请求超时',
type:'error',
duration:3000,
showClose: true,
})
return Promise.reject(error)
}
)
//添加响应拦截器
service.interceptors.response.use(
response => {
// loading close
loading.close();
return response
},
error => {
// loading close
loading.close();
Message({
message:error.message,
type:'error',
duration:3000,
showClose: true,
})
return Promise.reject(error)
}
)
/*
@func
@desc 后端返回数据 统一处理返回状态码,不同的状态码 执行不同的操作。
@param {object} a.data 后端返回的数据
@param {object} a.msg 后端返回的消息
@param {object} a.code 后端返回的状态码
@param {func} b Promise 成功回调
@param {func} c Promise 失败回调
*/
let responseCode = ({data, msg, code}, resolve ,reject) => {
// data 返回参数 msg 返回消息 code 返回状态
switch(code) {
// 请求成功
case 200:
// 成功回调
resolve(data);
break;
// 请求被拦截 需要重新登录账号
case 403:
invalidToken();
break;
// 其他状态
default:
Message({
message:msg,
type:'error',
duration:3000,
showClose: true,
})
// 失败回调
reject({
data,
msg,
code,
});
}
}
export default {
/*
@func
@desc axios get 请求
@param {string} a 接口地址
@param {object} b = {} 请求参数
*/
get(url, params = {}) {
return new Promise((resolve, reject) => {
service({
method: 'get',
url,
params,
}).then(({data}) => {
responseCode(data, resolve, reject);
}).catch(err => {
reject(err);
console.log(err, '异常')
})
})
},
/*
@func
@desc axios post 请求
@param {string} a 接口地址
@param {object} b = {} 请求参数
*/
post(url, data = {}) {
return new Promise((resolve, reject) => {
service({
method: 'post',
url,
data,
}).then(({data}) => {
responseCode(data, resolve, reject);
}).catch(err => {
reject(err);
console.log(err, '异常')
})
})
}
}
plug/index.js 插件 添加指令 实例方法 过滤器等
import axios from '@/api' // 封装的 axios 数据交互
import moment from 'moment' // 日期格式化
/*
@func
@desc 日期格式化
@param {number} a 时间戳
@param {string} b 格式
*/
let formatDate = (time, type) => {
let date = '';
// 如果传入无效的时间 返回空
if (!time) {
return date
}
switch(type) {
// 年月日时分秒
case 'YYYY-MM-DD HH:mm:ss':
date = moment(time).format('YYYY-MM-DD HH:mm:ss');
break;
// 年月日
case 'YYYY-MM-DD':
date = moment(time).format('YYYY-MM-DD');
break;
// 时分秒
case 'HH:mm:ss':
date = moment(time).format('HH:mm:ss');
break;
default:
console.error('vue-format-date 指令参数type格式错误 YYYY-MM-DD HH:mm:ss 或 YYYY-MM-DD')
}
return date;
}
//添加 全局的 指令 过滤器 实例方法等
export default {
install(Vue, options) {
// 添加全局过滤器 格式化日期
Vue.filter('formatDate', function(time, type) {
return formatDate(time ,type)
})
// 添加实例方法 ajax 数据交互
Vue.prototype.$axios = axios;
}
}
网友评论