美文网首页
vue-router考察问题

vue-router考察问题

作者: miao8862 | 来源:发表于2021-05-26 23:49 被阅读0次

    单页应用和多页应用的区别

    多页应用MPA 单页应用SPA
    应用组成 由多个完成页面构成 一个外部显示的页面 + 多个局部页面片段组成
    刷新方式 整页刷新 整体页面不刷新,只是页面片段局部刷新
    跳转后公共资源是否重新加载
    url模式 整个资源路径 http://xx/page1.html 哈希模式:http:xx/page#xxx;history模式:http:xx/page/xx
    用户体验 页面切换加载慢,不流畅,用户体验差,特别是在移动端 局部刷新,用户体验好,但首屏加载慢
    能否实现转场动画 不能
    页面间传递数据 依赖URL,cookie或localStorage,实现麻烦 同一页面,片段间传递数据简单
    SEO搜索引擎优化 直接做,简单 需要单独方案,比如服务端渲染,实现麻烦
    适用的范围 需要对搜索引擎友好的网站 对用户体验要求高的应用,特别是移动端
    开发难度 低一些,框架选择容易 高一些,需要专门的框架来降低这种模式开发,比如vue、react

    单页应用模式由于好处较多,已经是WEB开发的潮流,特别是移动应用开发

    单页应用其实就是将所有代码片段都进行模块化,然后组合成一个大模块,所以它首屏加载会比较慢。而且,组合成一个大模块时,会涉及到每个模块间的依赖关系以及如何控制哪些模块的展示问题,所以就有了路由模块的产生。

    路由模块帮助我们控制页面的显示问题,vue-router就是专门为vue设计的路由管理插件,这里基本概念我就不再介绍了,下面就介绍下路由守卫和用户权限控制。

    vue-router的路由守卫

    vue-router的路由守卫有三大类:

    全局守卫

    • beforeEach:当一个导航触发时,全局前置守卫按照创建顺序调用
    • beforeResolve:在所有组件内守卫和异步路由组件被解析之后被调用
    • afterEach: 导航被确认后调用

    路由独享守卫

    • beforEnter:在访问某个地址时,就会执行beforEnter中的操作,这种应用不多
    // router/index.js
    const routes = [
      {
        path: '/',
        name: 'home',
        beforeEnter: (to, from, next) => {
          // ...
        }
      }
    ]
    

    路由组件守卫

    • beforeRouteEnter: 在地址栏输入url,按下enter时调用
    • beforeRouteUpdate: 在当前路由改变,但是该组件被复用时调用,比如像这种只改变queryString的路由
    • beforeRouteLeave: 离开当前路由时被调用

    虽然路由守卫有很多种,但其实,我们在实际应用中用的最多的是beforeEach,其它的反正我在项目中是几乎没有应用过的,下面看下在项目中beforeEach的应用:

    // router/index.js
    const routes = [{...}]
    const router = new VueRouter({
      mode: 'history',
      routes
    })
    
    // 设置全局路由守卫
    router.beforeEach((to, from, next) => {
      // 如果没有登录,且要跳转的路由不是登录页,就跳转到登录页
      if(!isLogin && to.name !== 'login') {
        next({name: 'login'})
      }else {
        // 成功了,就继续正常页面跳转
        next()
      }
    })
    

    讲到路由守卫,一般就会扩展到用户权限问题,用户权限按照颗粒度,又会分为以下几种:

    用户权限

    1. 登录权限控制

    登录权限控制一般用于实现哪些页面需要登录才能访问,哪些页面是游客可以访问。

    一般我们登录校验的实现方式:

    • 在登录页面,登录后,向后台发送请求,获取登录信息,将其存储在本地存储中,这种方式一般有以下2种创建登录态:
      • 会话方式:将登录信息存储在cookie session中,每次请求带上登录态,现在这种方式用的也比较少,它容易受到CSRF的攻击
      • token方式:服务端使用JWT生成token,客户端将token存储到本地,在项目常用的是使用sessionStorage存储
    • 在访问其它页面时,使用beforeEach判断是否有登录态,如果有使用next()继续访问;如果没有,就跳转到登录页提示登录,我们可以在路由设置中通过meta去判断当前页面是否需要登录才能访问
    // router/index.js
    const routes = [
      {
        path: '/',
        name: 'home',
        meta: {
           needLogin: true
        }
      }
    ]
    
    // 设置全局路由守卫
    router.beforeEach((to, from, next) => {
      // 判断是否需要登录权限
      if(to.meata.needLogin) {
        // 如果没有登录,且要跳转的路由不是登录页,就跳转到登录页
        if(!isLogin && to.name !== 'login') {
          next({name: 'login'})
        }else {
          // 成功了,就继续正常页面跳转
          next()
        }
      }
    })
    
    2. 接口权限控制

    一般由请求头是否携带正常的token控制

    3. 页面权限/菜单控制
    • 在本地设置静态路由表和动态路由表,静态路由表是单纯的登录权限控制,而动态路由表存放的是需要角色权限控制的路由,初始时将路由表设置只有静态路由
    • 登录成功后,从服务器获取用户的权限字段(根据具体的系统设置对应的权限数据),存储在本地(推荐用vuex
    • 将获取到的用户权限字段与本地动态路由表作比对,将用户允许的路由通过router.addRoutes添加到路由表中
    • 当切换用户或退出用户,一种是刷新浏览器重新加载路由实例(这种用户体验不太好,实现简单);另一种是清空上个用户的路由栈,从而形成新的路由表

    这样,就可以实现角色的页面权限控制,即使用户强制输入没权限的路由也访问不到页面

    4. 内容(操作)权限控制

    内容权限控制是一种颗粒度更小的权限控制,用于控制不同角色对同一页面中的内容显示或隐藏。内容权限控制一般是由自定义指令来实现有。

    • 添加一个自定义指令,比如v-permission,在其中比对当前用户的权限字段,如果存在权限,则显示;否则删除对应的内容(dom)
    • 在要添加权限的内容上,添加自定义的权限编码
    app.directive('permission', {
      // 元素挂载完成后
      mounted(el, binding, vnode) {
        const per = binding.value; //获取元素上的权限编码
        const page = router.currentRoute.value.name; //获取当前路由名称
        const havePre = store.state.perList[page];  // 获取当前角色的内容权限
        if(!havePre.includes(per)) {
          // 如果没有权限,则删除这块内容
          el.parentElement.removeChild(el);
        }
      }
    })
    
    <!-- 给对应内容添加自定义的权限编码,可以用“CURD”指代增删改查权限 -->
    <button v-permission="c">添加</button>
    
    5. 数据权限

    数据权限就是所有用户都可以同样访问这一页面和操作页面,但不同的用户看到的数据内容是不一样的,这种权限控制,都是由服务器去控制的,这样才能保证数据安全。

    相关文章

      网友评论

          本文标题:vue-router考察问题

          本文链接:https://www.haomeiwen.com/subject/sohzjltx.html