vue中路由守卫(路由钩子,或者 叫做 路由导航守卫)一共有三种,一个全局路由守卫,一个是组件内路由守卫,一个是router独享守卫。
路由钩子,即导航钩子,其实就是路由拦截器,vue-router一共有三类:
全局钩子:最常用
路由单独钩子
组件内钩子
6.4.3.1 全局钩子(全局路由守卫)
所谓全局路由守卫,就是小区大门,整个小区就这一个大门,你想要进入其中任何一个房子,都需要经过这个大门的检查。 全局路由守卫有个两个:一个是全局前置守卫beforeEach(), 一个是全局后置守卫afterEach() 。
在src/router/index.js中使用,代码如下:
- // 给路由实例对象添加全局守卫
- // 全局前置守卫
- router.beforeEach((to,from,next)=>{
-
- // 读取数据
- let token = localStorage.getItem('token');
- console.log(token);
- if(token){//如果有token,就允许去访问 对应的组件
- next();//放行---页面执行放行操作
- }else{//如果没有token,就跳转到登录页
- if(to.path === '/login'){
- next();
- }else{
- next('/login');
- }
- }
-
-
- })
-
- export default router
每个钩子方法接收三个参数: to: Route : 即将要进入的目标 [路由对象] from: Route : 当前导航正要离开的路由 next: Function : 继续执行函数
next():继续执行
next(false):中断当前的导航。
next(‘/‘) 或 next({ path: ‘/‘ }):跳转新页面,常用于登陆失效跳转登陆
例如:
创建 user.vue 用户中心组件,login.vue登录组件。我们 希望 通过通过 登录且 成功登录,去访问用户中心,否则,做路由拦截。
user.vue
- <template>
- <div>
- <h1>用户中心</h1>
- </div>
- </template>
login.vue
- <template>
- <div class="login">
- <h1>系统登录</h1>
- <div class="login-box">
- <div>
- <!-- v-model.trim后面加上.trim是为了去除表单修饰符 -->
- 用户名:<input type="text" v-model.trim="username">
- </div>
-
- <div>
- 密 码:<input type="password" v-model.trim="password">
- </div>
-
- <div>
- <button @click="login">登录</button>
- </div>
- </div>
- </div>
- </template>
-
- <script>
- export default {
- name: 'login',
-
- data() {
- return {
- username:'',
- password:''
- };
- },
-
- mounted() {
-
- },
-
- methods: {
- login(){
- let result = this.username && this.password;
- if(!result){
- alert('用户名和密码不能为空');
- return false;
- }
-
- // 如果用户名不是admin,并且密码不是123456
- // 注意:用户名 和 密码 当其中有一个输入错误的时候,都会有下面这个提示
- if(this.username !== 'admin' || this.password !== '123456'){
- alert('用户名或密码错误');
- return false;
- }
-
- // 在登录的时候 同时 向 本地存储 存一个值,存到token中
- // 保存数据
- localStorage.setItem('token',Date.now());
-
- // 同上面那个一样,只是形式不同
- // localStorage.token = Date.now();
-
-
- // 登录成功
- // $router
- this.$router.push({path:'/user'})
- }
- },
- };
- </script>
-
- <style lang="scss" scoped>
- .login{
- display: flex;
- // 主轴垂直
- flex-direction: column;
- align-items: center;
- }
- .login-box div{
- margin: 10px 0;
- }
- .login-box input{
- outline: none;
- height: 26px;
- }
- .login-box button{
- width: 80px;
- height: 30px;
- }
- </style>
在路由配置文件中router/index.js 去配置 全局路由守卫(路由拦截):
- // 给路由实例对象添加全局守卫
- // 全局前置守卫
- router.beforeEach((to,from,next)=>{
-
- // 读取数据
- let token = localStorage.getItem('token');
- console.log(token);
- if(token){//如果有token,就允许去访问 对应的组件
- next();//放行---页面执行放行操作
- }else{//如果没有token,就跳转到登录页
- if(to.path === '/login'){
- next();
- }else{
- next('/login');
- }
- }
- // console.group('from---');
- // console.log(from);
-
- // console.group('to---');
- // console.log(to);
-
-
- })
使用:在路由配置中单独加入钩子,在src/router/index.js中使用,代码如下:
创建one.vue组件:
- <template>
- <div>
- <h1>我是首页组件中的子组件--one.vue</h1>
- </div>
- </template>
在src/router/index.js中, 在one组件中单独加 钩子:
- const routes = [
- // 定向
- {
- path:'/home',
- redirect:'/'
- },
- {
- path: '/',
- name: 'home',
- component: HomeView,
- // 嵌套路由(子路由)
- children:[
- {
- path:'/home/one',
- component:one,
- // 路由单独钩子(router独享守卫)
- beforeEnter:(to,from,next)=>{
- console.log('进入前执行');
- next();
- }
- }
- ]
- },
在HomeView.vue组件中,访问子组件:
- <template>
- <div class="home">
- <img alt="Vue logo" src="../assets/logo.png">
-
- <router-link to="/home/one">访问one组件</router-link>
- <router-view></router-view>
- </div>
- </template>
-
- <script>
-
- export default {
- name: 'HomeView',
- components: {
- }
- }
- </script>
预览: