vuex存取token,http简单封装、模拟登入权限校验操作、路由懒加载的几种方式、vue单页设置title
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;
vuex存取token,http简单封装、模拟登入权限校验操作、路由懒加载的几种方式、vue单页设置title的更多相关文章
- jQuery懒加载插件 – jquery.lazyload.js简单调用
Lazy Load 是一个用 JavaScript 编写的 jQuery 插件. 它可以延迟加载长页面中的图片. 在浏览器可视区域外的图片不会被载入, 直到用户将页面滚动到它们所在的位置. 这与图片预 ...
- Python爬虫-尝试使用人工和OCR处理验证码模拟登入
刚开始在网上看别人一直在说知乎登入首页有有倒立的汉字验证码,我打开自己的知乎登入页面,发现只有账号和密码,他们说的倒立的验证码去哪了,后面仔细一想我之前登入过知乎,应该在本地存在cookies,然后我 ...
- jquery实现简单瀑布流布局(续):图片懒加载
# jquery实现简单瀑布流布局(续):图片懒加载 这篇文章是jquery实现简单瀑布流布局思想的小小扩展.代码基于前作的代码继续完善. 图片懒加载就是符合某些条件时才触发图片的加载.最常见的具体表 ...
- jQuery模拟原生态App上拉刷新下拉加载
jQuery模拟原生态App上拉刷新下拉加载效果代码,鼠标上拉时会显示loading字样,并且会模拟加载一条静态数据,支持触屏设备使用. <!doctype html> <html ...
- Hibernate缓存和懒加载的坑你知道多少?这5个简单问题回答不上来就不敢说会用hibernate
问题1:session.flush()调用之后,懒加载还生效吗? 如果不生效,那是抛异常还是没有任何反应,或者直接返回null? 答案:生效.可以理解为在同一个session当中,懒加载只会执行一次. ...
- wow.js让css3动画变动更有趣(滚动页面动画模拟懒加载特效)
CSS3的出现给网站页面增加了活力,网站增色不少,有这么小小的一款插件就能做出很多动画效果. 最重要的是它:简单易用.轻量级.无需 jQuery......他就是wow.js 地址:https://d ...
- VUE图片懒加载-vue lazyload插件的简单使用
序:vue项目时候,我们要对图片进行懒加载处理,这个开发项目中就不需要自己去写了,因为比较方便使用vue lazyload进行处理,高效率开发 一. vue lazyload插件: 插件地址:http ...
- @Basic表示一个简单的属性 懒加载,急加载
5.@Basic(fetch=FetchType,optional=true) 可选 @Basic表示一个简单的属性到数据库表的字段的映射,对于没有任何标注的getXxxx()方法,默认 即为 @Ba ...
- vue-lazyload图片懒加载的简单使用
一.vue lazyload插件: 插件地址:https://github.com/hilongjw/vue-lazyload demo:http://hilongjw.github.io/vue-l ...
随机推荐
- 安装 Sublime Text 3及其插件
1. 安装 Sublime Text 3 虽然现在的 Sublime 3 还处于 beta 阶段, 但已经非常稳定了, 而且速度比 Sublime 2 得到了增强. Sublime 3 可以到官网下载 ...
- python中panda的dateframe
1 函数介绍 #to_csv函数的语法#函数原型# to_csv(filepath,sep=",",index=TRUE,header=TRUE)#参数介绍: #(1)导出的文件路 ...
- Flutter实战视频-移动电商-10.首页_FlutterSwiper轮播效果制作
10.首页_FlutterSwiper轮播效果制作 博客地址: https://jspang.com/post/FlutterShop.html#toc-5c2 flutter_swiper http ...
- php防盗链技术
在Http协议中,头信息里,有一个重要的选项: Referer Referer: 代表网页的来源,即上一页的地址 如果是直接在浏览器上输入地址,回来进来,则没有Referer头. 这也是: 为什么服务 ...
- Weekly Contest 78-------->809. Expressive Words (stack)
Sometimes people repeat letters to represent extra feeling, such as "hello" -> "he ...
- POJ3735【矩阵快速幂】
逛了一圈...觉得这篇讲的比较清楚:传送门~ 简要概括: 1.线性代数的知识,单位矩阵的利用:(如果不知道单位矩阵的,先去补习一下线代,做几题行列式就会了): 2.然后构造好矩阵以后,直接做M次乘积运 ...
- Codeforces691A【读题-水】
妈蛋wa了两次.. 时尚的定义是length大于1的要破个洞,一定要破个洞.. According to rules of the Berland fashion, a jacket should b ...
- OPENGL_变换与坐标系
参考:http://blog.csdn.net/kandyer/article/details/12449973 坐标系 世界坐标系:绝对坐标 物体坐标系:以物体自身为原点的坐标系 摄像机坐标系:以摄 ...
- 2014-5-24 NOIP模拟赛
Problem 1 护花(flower.cpp/c/pas) [题目描述] 约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时 ...
- jzoj5986. 【WC2019模拟2019.1.4】立体几何题 (权值线段树)
传送门 题面 题解 不难看出每个点的大小为行列限制中较小的那一个(因为数据保证有解) 对于行的每个限制,能取到的个数是列里限制大于等于它的数的个数,同理,对于列是行里大于它的个数(这里没有等于,为了避 ...