Vue2模拟动态路由权限

Vue权限

目录结构

  • gitee地址https://gitee.com/kkdaly/vue_permission.git
    .
    ├── README.md
    ├── babel.config.js
    ├── jsconfig.json
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── public  
    │   ├── favicon.ico
    │   └── index.html
    ├── src
    │   ├── App.vue   // 根vue文件
    │   ├── assets
    │   │   └── logo.png
    │   ├── components
    │   │   ├── home.vue   // 主页面
    │   │   ├── lmk  // lmk组件
    │   │   │   └── index.vue
    │   │   ├── login  // 登陆组件
    │   │   │   └── index.vue
    │   │   └── setting  // 设置组件
    │   │       └── index.vue  
    │   ├── main.js  // 入口摁键
    │   ├── router   // 路由
    │   │   ├── asyncRoute.js  // 动态路由文件
    │   │   └── index.js   // 路由主目录
    │   ├── store   // vuex
    │   │   ├── index.js
    │   │   └── module
    │   │       ├── menu.js  // 存储路由结构的数据
    │   │       └── user.js  // 存储用户的信息
    │   └── utils  // 配置文件
    │       ├── auth.js  // 获取token
    │       └── permision.js  // 权限文件
    └── vue.config.js  // vue配置文件
    

登陆权限

  • 可以在main.js文件里引入一个js文件让它打开网页的时候直接加载js文件
    console.log('权限运行了');
    
    import { getToken} from './auth.js'  // 获取token方法
    import router  from '@/router'  // 导入路由模块
    import store from '@/store'     // 导入vuex
    import asyncRoutes from '@/router/asyncRoute.js';   // 获取静态路由
    const FFF = ['/login']  // 目录白名单
    
    // 创建路由前置守卫
    router.beforeEach(async (to,from,next)=>{
        const token = getToken()  // 获取token
        if (token){  
            // 判断是否时向login
            if (to.path === '/login'){
                next('/') // 如果有token
            }else{
                // 如果不是到login
                // 获取用户的信息,这里不用登陆的原因是如果没登陆就跳转登陆,这里肯定是登陆过的
                // 判断vuex是否有用户信息,这里是通过token获取的用户信息,
                // 登陆之后会获取到token
                if (!store.state.user.userInFo.id){ // 判断vuex中是否有用户的id
                    const res = await store.dispatch('user/getUserInfo')  // 获取到用户信息,就获取到用户有访问那些路由的权限了
                    const menus = res.menus
                    // 过滤权限,将获取的用户权限和路由权限进行过滤,如果用户有这个路由权限就返回没有就忽略掉
                    const newRoute = asyncRoutes.filter(item => menus.includes(item.children[0].name))
                    // 将动态路由添加进去
                    router.addRoutes(newRoute)
                    store.commit('menu/SETMENULIST',newRoute) // 将过滤后的路由传到vuex home动态获取vuex的路由并渲染
                }
                next()  // 放行目录
            }
        }else{
            // 如果没有token
            if (FFF.includes(to.path)){ // 没有token会看白名单里的路由是不是当前访问的路由
                next() // 如果是就直接放行
            }else{
                next('/login') // 不是就跳转到login
            }
            
        }
    })

路由动态渲染

  • home.vue
    <template>
      <div class="hello">
         <el-col :span="24">
           <div class="grid-content bg-purple-dark">
           <el-menu  class="el-menu-demo" mode="horizontal" >
      <el-menu-item  v-for="route,l in routes" :key="l"><router-link :to="route.path">{{route.children[0].meta.title}}</router-link></el-menu-item>
    </el-menu>
          </div>
        </el-col>
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      name: 'HomeVue',
      data(){
        return {
        }
      },
      mounted(){
        console.log(this.$router.options.routes);
      },
      computed:{
        routes(){
          return this.$store.state.menu.menuList  // 从vuex获取路由信息渲染到前端
          // return this.$router.options.routes
        }
      },
      methods:{
      }
    }
    </script>
    
    <style scoped>
    
    </style>
    
  • store/menu.js
    import {constantRoutes} from '@/router'
    
    // 存储路由的模块
    export default {
        namespaced:"menu",
        state:{
            menuList:[
                ...constantRoutes  // 定义初始结构(初始数据里只有静态路由会被渲染)
            ]
        },
        mutations:{
            SETMENULIST(state,value){
                // 调用mutations后会将传来的动态路由value数据添加到menuList这样就可以自动渲染路由了
                state.menuList = [...constantRoutes,...value]
            }
        }
    }

本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!