目录
一,路由守卫:
路由守卫就是路由在跳转时的一些验证,列如登录鉴权,在项目里没有登录时不能跳转至个人中心页面...
2.1 路由守卫分为三大类:
- 全局守卫:前置守卫:
beforeEach
后置钩子:afterEach
- 单个路由守卫:独享守卫:
beforeEnter
- 组件内部守卫:
beforeRouteEnter、
beforeRouteUpdate、
beforeRouteLeave
参数:所有的路由守卫都有三个参数
to
: 要进入的目标路由(去到哪里)from
: 要离开的路由(从哪里来)next
: 是否进行下一步(还要不要继续)
写
next()
相当于next(true)
继续执行不写 相当于
next(false)
终止执行
next(path)
跳转 例如:next("/login")
注意:后置钩子afterEach
没有next
参数。
2.2 详细使用:
2.2.1 beforEach(
全局前置守卫 )
:
router.beforeEach((to, from, next) => {
if (to.meta.permission) {
if (sessionStorage.getItem("token")) {
next();
} else {
alert("请先登录");
next("/login");
}
} else {
next();
}
});
2.2.2 afterEach( 全局后置钩子 )用的比较少:
router.afterEach((to, from) => {
// to and from are both route objects.
});
2.2.3 单个路由守卫:
// 首页模块路由
{
path: "/index",
name: "index",
meta: { permission: true },
component: () => import("../views/Index.vue"),
beforeEnter: function(to, from, next) {
if (sessionStorage.getItem("token")) {
next();
} else {
alert("请先登录");
next("/login");
}
}
},
2.3 组件内部守卫:
2.3.1组件内部的守卫和data
、created
、mounted
、methods
是处于平等关系
2.3.2这里用beforeRouteEnter
举例说明:
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
// 不!能!获取组件实例 `this`
// 因为当守卫执行前,组件实例还没被创建
if (sessionStorage.getItem("token")) {
next();
} else {
alert("请先登录");
next("/login");
}
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
// 可以访问组件实例 `this`
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
// 可以访问组件实例 `this`
},
- beforeRouteEnter 是进入前
- beforeRouteUpdate 是路由变化时
- beforeRouteLeave 是离开后。这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消
注意:
- beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
二,鉴权:
2.1 登录鉴权案例展示:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../../vue.js"></script>
<script src="./vue-router.js"></script>
<style>
*{
margin: 0;
padding: 0;
}
#navgation{
position: absolute;
bottom: 0;
width: 100%;
height: 30px;
font-size: 18px;
background-color: rgba(127, 255, 212,0.5);
display: flex;
justify-content: space-around;
}
#navgation>a{
text-decoration: none;
width: 30%;
text-align: center;
}
#navgation .router-link-active{
background-color: rgba(127, 255, 212, 1);
color: seagreen;
}
.router-link-active{
color: steelblue;
}
</style>
</head>
<body>
<div id="app">
<div id="navgation" >
<router-link to="/home" >主页</router-link>
<router-link to="/news" >新闻</router-link>
<router-link to="/user" >我的</router-link>
</div>
<router-view></router-view>
</div>
</body>
<script>
const Home = {
template: `
<div>
<h1>Home页</h1>
</div>
`
}
const News = {
template: `
<div>
<h1>News页</h1>
</div>
`
}
const User = {
template: `
<div>
<h1>User页</h1>
</div>
`
}
const Login = {
template: `
<div>
<button @click = "login">登录</button>
</div>
`,
methods: {
login () {
// 定义一个token用来存储登录密钥
const token = 'sdkajfklsajdf';
// 实现浏览器本地存储
localStorage.setItem('access_token',token);
if(this.$route.params.fullPath){
this.$router.push(this.$route.params.fullPath)
}else{
this.$router.push('/home')
}
}
}
}
const NotFound = {
template: `
<div>
<h1>404</h1>
<h2>找不到页面</h2>
</div>
`
}
// 定义路由
const routes = [
// 路由规则
{
path: '/',
redirect: '/home' // 重定向到home页
},{
path: '/home',
name: '首页',
meta:{
needLogin: false
},
component: Home
},{
path: '/news',
name: '新闻',
meta:{
needLogin: true
},
component: News
},{
path: '/user',
name: '用户',
meta:{
needLogin: false
},
component: User
},{
path: '/login',
name: '登录',
component: Login
},{
// 定义404的路径
path: '*',
name: '404',
component: NotFound
}
]
const router = new VueRouter({
routes
})
router.beforeEach((to,from,next)=>{
const access_token = localStorage.getItem('access_token')
console.log(to);
if(to.fullPath == '/login' || to.fullPath == '/register' || access_token || !to.meta.needLogin){
next()
}else{
next({
name: '登录',
params: {
from: to.fullPath
}
})
}
})
const vm = new Vue({
el: '#app',
router,
})
</script>
</html>