zoukankan      html  css  js  c++  java
  • vue----vue-router

    概述

    Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。包含的功能有:

    • 嵌套的路由/视图表
    • 模块化的、基于组件的路由配置
    • 路由参数、查询、通配符
    • 基于 Vue.js 过渡系统的视图过渡效果
    • 细粒度的导航控制
    • 带有自动激活的 CSS class 的链接
    • HTML5 历史模式或 hash 模式,在 IE9 中自动降级
    • 自定义的滚动条行为

    安装

    vue-router 是一个插件包,所以我们还是需要用 npm/cnpm 来进行安装的。打开命令行工具,进入你的项目目录,输入下面命令。

    npm install vue-router --save-dev    //安装在开发环境
    npm install --save vue-router        //安装在生成环境

    如果在一个模块化工程中使用它,必须要通过 Vue.use() 明确地安装路由功能:

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    
    Vue.use(VueRouter);

    使用

    以下案例在 vue-cli 项目中使用 vue-router

    创建组件页面

      创建一个名为 src/components 的目录专门放置我们开发的 Vue 组件,在 src/components 目录下创建一个名为 Content.vue 的组件,代码如下:

      注意<template></template>中必须有一个<div/>,否则会报错

    <template>
        <div>
          我是内容页
        </div>
    </template>
    
    <script>
        export default {
            name: "Content"
        }
    </script>
    
    <style>
      #app {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
    </style>

    安装路由

    创建一个名为 src/router 的目录专门放置我们的路由配置代码,在 src/router 目录下创建一个名为 index.js 路由配置文件,代码如下:

    import Vue from 'vue'
    // 导入路由插件
    import Router from 'vue-router'
    // 导入上面定义的组件
    import Content from '@/components/Content'
    
    // 安装路由
    Vue.use(Router);
    
    // 配置路由
    export default new Router({
      routes: [
        {
          // 路由路径
          path: '/content',
          // 路由名称
          name: 'Content',
          // 跳转到组件
          component: Content
        }
      ]
    });

    配置路由

    修改 main.js 入口文件,增加配置路由的相关代码

    import Vue from 'vue'
    import App from './App'
    // 导入上面创建的路由配置目录
    import router from './router'
    
    Vue.config.productionTip = false;
    
    new Vue({
      el: '#app',
      // 配置路由
      router,
      components: { App },
      template: '<App/>'
    }); 

    使用路由

    修改 App.vue 组件,代码如下:

    <template>
      <div id="app">
        <router-link to="/">首页</router-link>
        <router-link to="/content">内容</router-link>
        <router-view></router-view>   //路由组件展示的地方
      </div>
    </template>
    
    <script>
    export default {
      name: 'App'
    }
    </script>
    
    <style>
      #app {
        font-family: 'Avenir', Helvetica, Arial, sans-serif;
        -webkit-font-smoothing: antialiased;
        -moz-osx-font-smoothing: grayscale;
        text-align: center;
        color: #2c3e50;
        margin-top: 60px;
      }
    </style>  

    说明:

    • router-link: 默认会被渲染成一个 <a> 标签,to 属性为指定链接
    • router-view: 用于渲染路由匹配到的组件

    效果演示

      访问:localhost:8080/#/content

    权限管理

    由于我们菜单栏是通过roles自动生成的,所以我们第一步,根据不同的用户返回不同的菜单(不能解决用户直接输入网址访问)

     1、给router设置属性,比如在mete中添加一个roles

    {
            path: "/",
            name: "dashboard",
            hidden: true,
            component: Layout,
            redirect: "/home", //父路由没有在mete中设置roles,表示任何人都可以访问
            children: [
                {
                    path: "/home",
                    name: "home",
                    meta: {title: '首页', icon: 'fa fa-home',roles:["admin","xx"]},  //子路由设置了roles,表示只有admin和xx可以访问
                    component: () => import("@/views/Home.vue")
                }
            ]
        },

     2、当用户登录的时候,保存user的时候,我们遍历routes中的每一个route,判断该路由时候被过滤掉(在actions.js中设置)

    import {routes} from "@/router";
    
    import {ActionTree} from 'vuex';
    import jwt_decode from 'jwt-decode';
    
    
    const actions: ActionTree<any, any> = {
        async setUser({state, commit}, user: any) {
            var jwtDecode:any = jwt_decode(user);
            //设置user信息
            commit('SET_USER', jwtDecode);
    
            //----------------设置用户访问路由的权限---------------------
            //获取jwtDecode中的user_roles,user信息中需要有user_roles(后台返回的)
            const { user_roles } = jwtDecode;
            //过滤路由(routes:当前的所有的路由)
            let accessedRouters = filterAsyncRouter(routes,user_roles);
            commit('SET_ROUTERS', accessedRouters);
        }
    }
    
    /**
     * 递归对routers进行过滤,返回routers
     * route:当前路由对象
     */
    function filterAsyncRouter(asyncRouterMap: Array<any>,roles:any) {
        const accessedRouters = asyncRouterMap.filter(route => {
            if (hasPermission(roles,route)) {
                if (route.children && route.children.length) {
                    route.children = filterAsyncRouter(route.children,roles);
                }
                return true;
            }
            return false;
        });
        return accessedRouters;
    }
    
    /**
     * 判断是否有权限
     * @param roles 当前角色
     * @param route 当前路由对象
     * */
    function hasPermission(roles: any, route: any) {
        if (route.meta && route.meta.roles) {
            //roles是自己设置的一个数组
            return route.meta.roles.some((role: string) => role.indexOf(roles) >= 0)
        }else {
            //如果当前路由对象routes.meta没有roles属性,表示任何人都可以访问路由
            return true;
        }
    }
    
    export default actions;

    解决用户直接输入网址访问的问题

    import jwt_decode from 'jwt-decode';
    router.beforeEach((to, form, next) => {  //拦截上面配置的路由
        // 获取用户登录状态
        var isLogin = localStorage.getItem("token") != null ? true : false;
    
        // 注销
        if (to.path == '/logout') {
            // 清空
            localStorage.clear()
            // 跳转到登录
            next({path: '/login'});
        }
    
        if (to.path != '/login' && to.path != '/password') {
            //如果没有登录
            if (isLogin == false) {
                next({path: '/login'});
            }
            //如果已经登录,判断是否具有访问该路由的资格
            else {
                const decoded: any=jwt_decode(localStorage. tsToken);
                const { user_roles }=decoded;
                // @ts-ignore
                if (hasPermission(user_roles,to)) {
                    next();
                } else {
                    next('/404'); // 没有权限进入
                }
            }
    
        }
        // 下一个路由
        next();
    });
    function hasPermission(roles: any, route: any) {
        if (route.meta && route.meta.roles) {
            //roles是自己设置的一个数组
            return route.meta.roles.some((role: string) => role.indexOf(roles) >= 0)
        }else {
            //如果当前路由对象routes.meta没有roles属性,表示任何人都可以访问路由
            return true;
        }
    }
    export default router
    

      

  • 相关阅读:
    单链队列
    栈的顺序存储表示
    顺序队列
    串的定长顺序存储表示
    串的堆分配存储
    双向循环链表
    单循环链表的表示和实现
    串的块链存储表示
    线性表的顺序表示和实现
    线性表的单链表表示和实现
  • 原文地址:https://www.cnblogs.com/yanxiaoge/p/11103702.html
Copyright © 2011-2022 走看看