使用vue-router导航守卫来实现token登录页面跳转
- 1 介绍
- 2 主要知识点
-
- 2.1 导航守卫
- 2.2 存储设置token
- 2.3 清除token
- 2.4 获取token
- 3 其他重要知识点
-
- 3.1 编程式导航API
- 3.2 嵌套路由
- 3.3 动态路由
-
- 3.3.1 传数据给router
- 3.3.2 router通过:id接收
- 3.3.2 获取$route参数对象
-
- 3.3.2.1 this.$route.params
- 3.3.2.2 props传参
- 4 indexOf
-
- 4.1 数组调用
- 4.2 字符串调用
- 5 效果图
有什么不懂的可以私信我!!!
1 介绍
需求介绍
本次是实现一个简单的登录页面跳转到多个页面的过程,跳转页面也附带了一些条件
1.每次登录要进行存储token
2.每次登录退出进行清除token
3.阻止修改url上hash参数进行访问后台主页,这里用到的是导航守卫beforeEach进行检测本地存储中是否有token,要是有token就能访问后台主页,没有就不能
2 主要知识点
2.1 导航守卫
每次发生路由的导航跳转时,都会触发全局前置守卫,有 3 个形参
A->C
1.to函数是将要访问的路由对象 C
2.from函数是将要离开路由对象 A
3.next函数表示放行
// 只要发生了路由的跳转 必然会触发beforeEach指定的function回调函数
router.beforeEach((to,from,next)=>{
//需要检查是否登录的白名单
const pathArr=[
'/home',
'/home/yonghu',
'/home/quanxian',
'/home/shangpin',
'/home/dingdan',
'/home/xitong',
'/home/userinfo'
]
// A->C
// to函数是将要访问的路由对象 C
// from函数是将要离开路由对象 A
// next函数表示放行
// 分析
// 1.要拿到用户将要访问的hash地址
// 2.判断hash地址是否等于/Main
// 2.1.如果等于/Main.证明要登录之后,才能访问成功
// 2.2.如果不等于/Main,则不需要登录,直接放行next()
// 3.如果访问的地址时/Main,则需要读取localStorage中的token值
// 3.1如果有token,则放行
// 3.2如果没有token,则强制跳转到/login登录页
// 要是多个页面都需要token检测
// 找to.path在不在这个pathArr数组里面,要是等于-1就是不在,不等于-1就是在
if(pathArr.indexOf(to.path) !== -1){
// 要访问后台主页,需要判断是否有token
const token=localStorage.getItem('token')
if(token){
next()
}else{
next('/login')
}
}else{
next()
}
})
2.2 存储设置token
在登录的时候通过点击事件调用submit这个方法
submit(username,password){
console.log(username);
console.log(password);
if(username=='123' && password=='123'){
// 登录成功存储设置token
localStorage.setItem('token','whl 123123')
console.log('登录成功');
this.$router.push('/home')
}else{
// 登陆失败清除toekn
localStorage.removeItem('token')
console.log('登录失败');
}
},
2.3 清除token
2.4 获取token
const token=localStorage.getItem('token') //获取之后,用token变量进行接收
console.log(token)
3 其他重要知识点
3.1 编程式导航API
在浏览器中,调用 API 方法实现导航的方式,叫做编程式导航。例如:
⚫ 普通网页中调用 location.href 跳转到新页面的方式,属于编程式导航
⚫ vue-router 提供了许多编程式导航的 API,其中最常用的导航 API 分别是:
⚫ 跳转到指定 hash 地址,并增加一条历史记录
this.$router.push('hash地址') //这里的hash地址就是router文件夹下index.js跟组件的对应关系
⚫ 跳转到指定的 hash 地址,并替换掉当前的历史记录
this.$router.replace('hash地址')
⚫ 实现导航历史前进、后退
this.$router.go(数值 n)
//在实际开发中,一般只会前进和后退一层页面。因此 vue-router 提供了如下两个便捷方法:
⚫ 在历史记录中,后退到上一个页面
this.$router.back()
⚫ 在历史记录中,前进到下一个页面
this.$router.forward()
3.2 嵌套路由
1.router-view:只要在项目中安装了和配置了vue-router,就可以使用vue-router这个组件(占位符)
2.router-link:当安装了vue-router后,就可以使用router-link代替a链接
<a href="#/movie">电影</a>
<router-link to="/movie">电影</router-link>
3.这里要注意的是第一个router-view和第二个router-view没有任何关联,可以这么理解第一个是在父组件中,第二个在子组件中,在不同的页面中各自调用router-link来进行使用router-view展示不一样的内容
<router-link to="/about">tab1</router-link> //children的path为空,叫做默认子路由,{path:'',component:Tab1}
<router-link to="/about/tab2">tab2</router-link>
<hr>
<router-view></router-view>
//src.router.index.js是当前项目的路由模块
// 1.导包
import Vue from 'vue'
// VueRouter是构造函数,要new实例
import VueRouter from 'vue-router'
import Home from '@/components/Home.vue'
import Movie from '@/components/Movie.vue'
import About from '@/components/About.vue'
import Tab1 from '@/components/tabs/Tab1.vue'
import Tab2 from '@/components/tabs/Tab2.vue'
//2.调用vue.use()给vue装插件,把VueRouter安装为vue插件
Vue.use(VueRouter)
// 3.创建路由的实例对象
const router=new VueRouter({
// routes是一个数组,作用定义"hash地址"与"组件"之间的关系
routes:[
//路由规则
// 当用户访问 / 的时候,通过redirect跳转到/home对应的路由规则
{path:'/',redirect:'/home'},
{path:'/home',component:Home},
{path:'/movie',component:Movie},
{
//about页面的路由规则(父级路由规则)
path:'/about',
component:About,
// 通过children嵌套声明子级路由的规则
children:[
//默认子路由:如果children数组中,某个路由的规则的path空值
// 为空字符串,则这条路由规则,叫做”默认子路由“
{path:'',component:Tab1},
{path:'tab2',component:Tab2}
]
},
]
})
// 4.向外共享路由的实例对象
export default router
3.3 动态路由
把hash地址中可变的部分定义为参数项,从而提高由规则的复用性
比如项目中让你开发一个商品和商品详情页面,点击详情按钮,就能跳转到商品详情页面,这时候就用到了动态路由,除了简单易用之外,更大的作用就是能够让商品详情页面获取到不一样的id,从而每个商品详情页面获取到不一样的商品数据。
3.3.1 传数据给router
<a href="#" @click.prevent="xiangqing(item.id)">详情</a>
xiangqing(id){
this.$router.push('/home/userinfo/'+id)
}
3.3.2 router通过:id接收
const router = new VueRouter({
// path里面的hash地址不能够是大写
routes:[
// redirect重定向/login,再指向component的
// Login渲染到router-view
{path:'/',redirect:'/login'},
{path:'/login',component:Login},
{
path:'/home',
component:Home,
redirect:'/home/yonghu',
children:[
// 要是子路由中,某个path为空值,默认子路由(默认展示)
// children不需要添加/
{path:'yonghu',component:MyUsers},
{path:'quanxian',component:MyRights},
{path:'shangpin',component:MyGoods},
{path:'dingdan',component:MyOrders},
{path:'xitong',component:MySettings},
// :id主要租用就是;因为是详情,就通过id来进行区分
{path:'userinfo/:id',component:MyUserDetail,props:true},
]
},
]
})
3.3.2 获取$route参数对象
3.3.2.1 this.$route.params
在对应的方法下直接使用
3.3.2.2 props传参
前提:在router对应关系中,一定要开启 props:true上上方的代码已经写上
props:['id'] //进行注册
{{id}} //使用
props:true //router对应关系中一定要开启
4 indexOf
在导航守卫中用到了indexOf
4.1 数组调用
要是不满足条件就返回-1
let food= ["1", "2", "3", "4"];
let a = food.indexOf("4");
console.log(a) // 3
let b= food.indexOf("5");
console.log(b) // -1
4.2 字符串调用
可返回某个指定的字符串值在字符串中首次出现的位置,并区分大小写
let str="Hello world!";
console.log(str.indexOf("Hello"));//0
console.log(str.indexOf("world"));//6
console.log(str.indexOf("World") );//-1