浅谈路由守卫的权限设置

路由守卫

  • 作用:监听路由的变化

    • 关于更新你点击的页面,显示对应的标题!
    • 这就需要在监听路由的跳转,实时的显示对应的标题!
  • 官网:https://router.vuejs.org/zh/guide/advanced/navigation-guards.html#%E5%85%A8%E5%B1%80%E5%89%8D%E7%BD%AE%E5%AE%88%E5%8D%AB

    • to => 去往那个路由
      • 由于to去往的路由,可能存在路由的嵌套,那么最好的话,使用 to.matched[0] 取出第一个路由
    • from => 从那个路由跳转
    • next() => 就是一个管道运输,执行下一个的钩子函数,如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
  • 全局守卫

    • 全局前置路由守卫 => router.beforeEach(function(to,from,next){})
    • 全局后置路由守卫 => router.afterEach(function(to,from){})
    • 注意点:这个全局路由守卫是,配置在router/index.js 路由文件下的
    router.beforeEach((to, from, next) => {
      document.title = to.meta.title
      console.log(to);
      next();
    })
    
  • 组件内的守卫

    • beforeRouteEnter(to, from, next) {}
      • 进入当前路由执行前,组件实例还没被创建
    • beforeRouteUpdate(to, from, next) {} (2.2 新增)
      • 在当前路由改变,但是该组件被复用时调用
        • 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        • 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        • 可以访问组件实例 this
    • beforeRouteLeave(to, from, next) {}
      • 导航离开该组件的对应路由时调用
      • 可以访问组件实例 this
    • 注意点:组件内使用时配置这个路由守卫即可!
    methods:{
    
    },
    beforeRouteEnter(to, from, next) {
      console.log("我是Edit组件,进入组件前", to);
      next();
    },
    beforeRouteUpdate(to, from, next) {
      console.log("我是Edit组件,路由更新,复用组件", to);
      next();
    },
    beforeRouteLeave(to, from, next) {
      console.log("我是Edit组件,离开当前组件,去往", to);
      next();
    },
    
  • 路由独享的守卫

    • 你可以在路由配置上直接定义 beforeEnter 守卫:
    const router = new VueRouter({
      routes: [
        {
          path: '/foo',
          component: Foo,
          beforeEnter: (to, from, next) => {
            next()
          }
        }
      ]
    })
    

路由的执行步骤

  1. 导航被触发。
  2. 在失活的组件里调用beforeRouteLeave离开守卫。
  • 所谓失活组件,就是从当前组件离开,去往下一个组件,这个当前组件就是失活组件
  1. 调用全局的 beforeEach 守卫。
  2. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  • 就是两个路由路径一致的时候,就参数不一致,那么两者切换的时候,会复用前一个组件的内容!
  1. 在路由配置里调用 beforeEnter。
  2. 解析异步路由组件。
  3. 在被激活的组件里调用 beforeRouteEnter。
  • 所谓激活组件,就是从上一个组件离开,来到当前组件,这个当前组件就是激活组件
  1. 调用全局的 beforeResolve 守卫 (2.5+)。
  2. 导航被确认。
  3. 调用全局的 afterEach 钩子。
  4. 触发 DOM 更新。
  5. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

路由守卫相关操作

点击当前组件,显示对应title

  • 01:需要在路由配置的时候,设置一个meta对象,里面有着title属性 => 这是关于需要显示的title
  • 02:需要使用路由守卫, => 取出从哪里跳转到哪里路由的title属性

router/index.js

 //路由守卫
 router.beforeEach((to, from, next) => {
   document.title = to.matched[0].meta.title
    <!-- document.title = to.meta.title  -->
   next();
 })
import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

const routes = [{
    path: '/',
    name: 'Home',
    meta: {
      title: "首页"
    },
    component: Home
  }, {
    path: '/profile/:id/:name',
    name: 'Profile',
    meta: {
      title: "档案"
    },
    component: () => import('../views/Profile.vue')
  }, {
    path: '/news',
    name: 'News',
    meta: {
      title: "新闻"
    },
    component: () => import('../views/News.vue')
  }
]

const router = new VueRouter({
  // mode: 'history',
  // base: process.env.BASE_URL,
  routes
})

//路由守卫
router.beforeEach((to, from, next) => {
  document.title = to.matched[0].meta.title
  next();
})
export default router

使用路由守卫的方式实现登录跳转判断!

  • 需求:
    • 当你点击列表之中的 用户列表 但是你没有登录 那么像跳转到登录组件
    • 当你登录完成后,那么再重新跳转回到 用户列表 组件!
router/index.js路由的配置
  • 对于每一个路由都需要设置 授权管理 使用 meta:{} => meta字段(元数据) => 里面可以书写 title requireAuth 等!

      {
        path: "/user",
        meta: {
          title: "用户",
          requiresAuth: true
        },
        component: () => import("../pages/user/Default.vue"),
        children: [{
            path: "/",
            redirect: "list"
          }, {
            path: "list",
            name: "UserList",
            meta: {
              title: "用户列表"
            },
            component: () => import("../pages/user/List.vue")
          },
          {
            path: "add",
            name: "UserDdd",
            meta: {
              title: "用户添加"
            },
            component: () => import("../pages/user/Edit.vue")
          }, {
            name: "UserEdit",
            path: "edit/:id",
            meta: {
              title: "用户编辑"
            },
            component: () => import("../pages/user/Edit.vue")
          }
        ]
      },
    
  • 在全局前置路由守卫 之中 判断当前路由是否登录了,才可访问! 判断是否授权 => requiresAuth

    • to.matched.some(item =>item.meta.requireAuth)
      //判断目标路由是否需要登录 才可访问!
      //当匹配的路由 项之中 有这个授权请求 那么就先从本地拿一下 本地的存储用户信息!
      router.beforeEach(function (to, from, next) {
      //判断当前路由是否需要登录授权!,才能访问
      if (to.matched.some(item => item.meta.requiresAuth)) {
        //从本地拿到 存储的userInfo信息!
        let userInfo = localStorage.getItem('userInfo') || {};
        try {
          userInfo = JSON.parse(userInfo)
        } catch (err) {
          userInfo = {}
        }
        // 判断当前用户信息是否包含token
        if (userInfo.authorization) {
          next();
        } else {
          //若不存在 token 那么就去往 登录页面!
          next({
            path: "/home/loginout",
            query: {
              // 跳转到登录页面,并传递 当前点击想要去的 目标页面路径
              redirectTo: to.fullPath
            }
          })
        }
      } else {
        next();
      }
    })
    

LoginOut.vue组件 之登录按钮

  • 这边包含验证码! 注意点:就是svg验证码 是一个 html标签 那么定义一个变量vcodeSvg 来接受,然后使用v-html=“vcodeSvg”
    //点击 验证码 发起请求 由于最开始需要验证码 需要在created(){} 之中 先调用一下这个方法!
      async getVcode() {
        const res = await this.$request.get("/vcode");
        this.vcodeSvg = res.data.data;
      },
    
  • 点击登录:
    • 先验证过了,然后在发起请求!
        const res = await this.$request.get("mlogin",{
          params:{
            ...this.ruleFrom //拿到表单的值 发起请求
          }
        })
      
    • 发起请求后,返回数据,判断是否成功,成功的话 那么先把返回来的用户信息存入本地之中
      localStorage.setItem("userInfo", JSON.stringify(res.data.data));
    • 点击登录后,需要返回原本用户 想要去对应path
        //this.$route.query 这是路由配置之中 设置的返回的那个想要去的目标path 参数! 重定向To 默认为home
        const { redirectTo = "/home" } = this.$route.query 
        this.$router.replace(redirectTo);
      
  <div class="login-wrap">
    <el-form
      :label-position="labelPosition"
      label-width="80px"
      class="login-form"
      :model="ruleForm"
    >
      <h2>用户登录</h2>
      <el-form-item label="用户名">
        <el-input v-model="ruleForm.username"></el-input>
      </el-form-item>
      <el-form-item label="密码">
        <el-input v-model="ruleForm.password"></el-input>
      </el-form-item>
      <el-form-item label="验证码" prop="vcode">
        <el-input v-model="ruleForm.vcode">
          <template v-slot:append>
            <div v-html="vcodeSvg" class="vcode" @click="getVcode"></div>
          </template>
        </el-input>
      </el-form-item>
      <el-form-item>
        <el-checkbox label="下次免登陆" v-model="ruleForm.mdl"></el-checkbox>
      </el-form-item>
      <el-button type="primary" class="login-btn" @click.prevent="handleLogin">登录</el-button>
    </el-form>
  </div>
  data() {
    return {
      labelPosition: "left",
      vcodeSvg: "", //用于存放 请求回来的svg验证码这个html标签
      ruleForm: {
        username: "",
        password: "",
        vcode: "",
        mdl: true,
      },
    };
  },
  created() {
    //一开始 发起请求 拿到验证码!
    this.getVcode();
  },
  methods: {
    async handleLogin() {
      console.log(1, this.ruleForm);
      // 一进入登录界面的时候,就发起请求 请求验证码!
      const res = await this.$request.get("/mlogin", {
        params: {
          ...this.ruleForm,
        },
      });
      // console.log("我是点击登录", res.data.data);
      if (res.data.code === 1) {
        this.$message.success("登录成功");
        localStorage.setItem("userInfo", JSON.stringify(res.data.data));
        //路由守卫 设置了 最开始 点击那里 就返回那个的path
        const { redirectTo = "/home" } = this.$route.query;
        this.$router.replace(redirectTo);
      }
    },
    async getVcode() {
      const res = await this.$request.get("/vcode");
      this.vcodeSvg = res.data.data;
    },
  },
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值