zoukankan      html  css  js  c++  java
  • VUE 动态路由

      因公司业务的发展,需要做一款新的产品,该产品分为:用户端和后台管理。我负责后台管理系统的开发。在看了UI的设计图后,又因为产品的周期较短,所以,我果断采用了vue-element-admin 来快速的搭建后台管理系统。这里我主要说下在这个过程中用到的动态路由,简单的总结下。

    vue-element-admin 本身的动态路由 (个人的理解)

    • 登录成功后获取token,根据 token 来获取用户信息和权限

      const { roles } = await store.dispatch('user/getInfo')
      // generate accessible routes map based on roles
      const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
      
    • 事先把不需要权限都能访问的路由 和 需要权限访问的路由都分配好后,在permission文件中导入

      import { asyncRoutes, constantRoutes } from '@/router'
      
    • 再调用 action 里的 generateRoutes 方法来根据用户的权限对路由进行不同的处理,并存储在state中

      generateRoutes({ commit }, roles) {
        return new Promise(resolve => {
          let accessedRoutes
          if (roles.includes('admin')) {
            accessedRoutes = asyncRoutes || []
          } else {
            accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
          }
          commit('SET_ROUTES', accessedRoutes)
          resolve(accessedRoutes)
        })
      }
      
      export function filterAsyncRoutes(routes, roles) {
        const res = []
      
        routes.forEach(route => {
          const tmp = { ...route }
          if (hasPermission(roles, tmp)) {
            if (tmp.children) {
              tmp.children = filterAsyncRoutes(tmp.children, roles)
            }
            res.push(tmp)
          }
        })
      
        return res
      }
      
      function hasPermission(roles, route) {
        if (route.meta && route.meta.roles) {
          return roles.some(role => {
            return route.meta.roles.includes(role)
          })
        } else {
          return true
        }
      }
      
    • 将生成的路由通过addRoutes动态添加进去

      router.addRoutes(accessRoutes)
      
    • 将state中的路由通过getters暴露出去,并生成侧边栏

      permission_routes: state => state.permission.routes,
      
      <el-scrollbar wrap-class="scrollbar-wrapper">
        <el-menu
          :default-active="activeMenu"
          :collapse="isCollapse"
          :background-color="variables.menuBg"
          :text-color="variables.menuText"
          :unique-opened="false"
          :active-text-color="variables.menuActiveText"
          :collapse-transition="false"
          mode="vertical"
        >
          <sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
        </el-menu>
      </el-scrollbar>
      

      我自己在此基础上改动的动态路由

        因为上述的动态是动态获取用户的权限来生成对应的路由的,登录成功后生成的路由不会在切换页面时发生改变。这和我们交互需求不符合,而且我们后端的登录接口,是一下将用户的token和用户的信息都返回了,并且没有用户的权限,也就是说我们的用户所有页面都是可以访问的。

      我的思路

      • 我将所有的路由都分配成了可访问的同步路由,没有异步路由

      • 并将所有的页面 (除登录、404页面),都在meta中添加了roles,并根据需求为每个页面添加对应的权限属性值。

      • permission 中定义了一个变量来表示路由状态,并定义对应的修改方法,最后将变量暴露出去,并将状态存储到了 sessionStorage 中

        routerstatus: sessionStorage.getItem('ifrouter') || false
        
      • 在渲染侧边栏的时候监听该值的变化,定义 setTimeout 的原因是当该值发生变化后,发现侧边栏不动态改变,而试了this.$forceUpdate()没有用,就采用这个方法

        watch: {
          routerstatus(newv, oldv) {
            if (newv) {
              this.ifRouter(this.transferarr)
            } else {
              this.ifRouter(this.outsidearr)
            }
            sessionStorage.setItem('ifrouter', newv)
            this.isshow = false
            const timer = setTimeout(() => {
              this.isshow = true
              clearTimeout(timer)
            }, 500)
          }
        },
        <!-- 这里的代码和我上述的思路有一定的出入,后续优化掉,更新掉 -->
        ifRouter(routerarr) {
          const temp_route_arr = this.$router.options.routes
          for (let i = 0; i < temp_route_arr.length; i++) {
            if (temp_route_arr[i].children && routerarr.includes(temp_route_arr[i].children[0].name)) {
              temp_route_arr[i].hidden = false
            }
            if (temp_route_arr[i].children && !routerarr.includes(temp_route_arr[i].children[0].name)) {
              temp_route_arr[i].hidden = true
            }
          }
        }
        <!-- 这里是稍作优化后的代码,随后有优化,会及时的更新 -->
        ifRouter(control) {
          const temp_route_arr = this.$router.options.routes
          for (let i = 0; i < temp_route_arr.length; i++) {
            if (temp_route_arr[i].meta && temp_route_arr[i].meta.roles.includes(control)) {
              temp_route_arr[i].hidden = false
            } else {
              temp_route_arr[i].hidden = true
            }
          }
        }
        
      • 这样通过动态的改变某个页面路由的 hidden 属性,来显示或隐藏页面,可以实现在切换页面时来动态改变侧边栏

      有想法的欢迎留言,一起学习成长

  • 相关阅读:
    三个心态做人做学问 沧海
    成功走职场要找准自己的"快捷键" 沧海
    免费离线下载 拂晓风起
    Hibernate 获取某个表全部记录时 奇怪现象 (重复出现某个记录) 拂晓风起
    无法读取mdb 如果连接不了ACCESS mdb文件,就尝试安装MDAC 拂晓风起
    Netbeans 使用 Hibernate 逆向工程 生成hbm和pojo 拂晓风起
    如何点击单选框 radio 后面的文字,选中单选框 拂晓风起
    Java 连接access 使用access文件 不用配置 拂晓风起
    mysql下如何执行sql脚本 拂晓风起
    Hibernate配置access Hibernate 连接 access 拂晓风起
  • 原文地址:https://www.cnblogs.com/aloneer/p/15063758.html
Copyright © 2011-2022 走看看