vue实战:HTTP路由拦截

vue中有“三霸”:拦截器、路由守卫、导航守卫。
他们都有一个共同的作用(…也可能是唯一的作用) —— 在路由变更前做一次判断,或取或舍,或添加token、session之类的【头信息】。

fj

拦截器

我们先看其工作原理:
tp

其基本用法:

Vue.http.interceptors.push((request,next)=>{
	//请求发送前的处理逻辑
	next((response)=>{
		//请求发送后的处理逻辑
		return response;
	})
})

拦截器是一个全局性的处理函数(工具),它的局限也是“全局”:所有请求都要统一处理,所以用的地方不多 —— 泛用性提示:提示框!

当与服务器进行通信时,我们显示一个“ 加载中… ”的拦截画面隔绝用户进行其他的操作,待处理完成后再去删除加载画面。
这里我们不妨使用UI组件,但是这个不重要,重点是 我们要将拦截器代码写在main.js文件里 ,因为它是一个全局性方法:

Vue.http.interceptors.push((request,next)=>{
	if(request.url.includes('/api/')){
		let modal=window.UIkit.modal.blockUI(`
			<div class="uk-modal-spinner"></div>
			<p class="uk-text-center">加载中...</p>
		`,{
			center:true
		})

		next((response)=>{
			modal.hide();
			return response;
		})
	}
})

这样在每次向服务器发送请求时就会先在页面显示出一个“加载中…”的loading框。

tj

一般我们使用的是【axios】,不会像上面代码中那样做拦截 —— axios拦截器分为request拦截器和response拦截器两种,而且他们一般一起使用!
下面是笔者做的一个项目中为登录添加token的示例:
新增文件setaxios.js

export default function setAxios(){
	axios.interceptors.request.use(config=>{
		if(store.state.token){
			config.headera.token=store.state.token
		}
		return config
	},error=>{
		return Promise.reject(error)
	})
	
	axios.interceptors.response.use(response=>{
		if(response.status==200){
			const data=response.data
			if(data.code==-1){
				store.commit('settoken','')
				localStorage.removeItem('token')
				router.replace({path:'/login'})
			}
			return data
		}
		return response
	},error=>{
		return Promise.reject(error)
	})
}

然后就可以在main.js文件里添加:

import setaxios from './setaxios'
setaxios();

tj

配置“路由守卫”

让我们来到router.js文件中 —— 这里是“路由”的“聚集地”。

其实每个router对象中都有一个meta属性(这可能是因为编译成HTML的缘故吧):它有一个字段requireAuth

{
	path:'xxx',
	name:'xxx',
	meta:{
		requireAuth:true
	},
	component:()=>import('./xx/xxx')
},
//...

有了这个字段且值为true时,我们就默认为这个路由页面需要有登录权限的。
所以,
配置完上面,我们要回到main.js文件:在这里(new Vue之外)添加

导航守卫

router.beforeEach((to,from,next)=>{
	//无论是刷新还是跳转路由,第一个进入的就是这个路由前置钩子函数
	store.commit('settoken',localStorage.getItem('token'))
	if(to.meta.requireAuth){
		if(store.state.token){
			next()
		}else{
			next({
				path:'/login',
				query:{redirect:to.fullPath}
			})
		}
	}else{
		next()
	}
})

这样,我们就可以在login.vue页面判断跳转 —— 实现“再次进去返回到原页面而不是跳转到首页”的功能:

if(this.$route.query.redirect){
	this.$router.replace({path:this.$route.query.redirect})
}else{
	this.$router.replace({path:'/xxx/xxx'})
}

tj

导航守卫还可以用在组件内部:比如前面提到的loading

<div v-if="state==loading">
	is loading...
</div>
<div>
	<h1>{{userInfo.name}}</h1>
</div>

//js代码
data(){
	return{
		state:'loading',
		userInfo:{}
	}
},
mounted(){
	this.init();
}beforeRouteUpdate(to,from,next){
	this.state='loading'
	this.init()
	next()
},
methods:{
	init(){
		fetch(`/api/usr/${this.$route.params.id}`)
			.then((res)=>res.json)
			.then((data)=>{
				this.state='';
				this.userInfo=data;
			});
	}
}
原创文章 198 获赞 554 访问量 10万+

猜你喜欢

转载自blog.csdn.net/qq_43624878/article/details/105432653