• Vue路由使用(router)


    介绍

    vue-router相当于vue内部跳转链接,将需要切换的页面在vue-router里注册,在项目里配置就能完成页面的切换,它不仅能完成项目的切换,还能实现参数的传递,它还有个很重要的功能路由导航守卫(导航守卫分为前置导航守卫,后置导航守卫,组件内置导航守卫,常用就是前置导航守卫,设置用户登录可访问的界面和未登录可访问的界面,也相当于二次拦截,(axios请求拦截器是第一次拦截))。

    路由跳转和传参

    重点:
    vue-router中,有两大对象被挂载到了实例this
    $route(只读、具备信息的对象);
    $router(具备功能的函数);

    • 1.router-link(类似a标签)

    路由配置:

    // 路由配置
     {
       path: '/pkproperties', // 路径
       name:'pkproperties', // 路由名,path路径必写,用name跳转的时候是根据name名找到path进行跳转
       component: () => import('@/views/pkproperties'), // 组件(组件文件名为index的可省略),路由懒加载写法
       redirect: '', // 路由重定向,就是当一个页面需要切换多个路由的时候,这里面填的是首次进入页面展示的路由组件地址
       hidden: truechildren: [] // 嵌套路由,当一页有很多路由需要切换的时候,就需要用到嵌套路由
      },
      
    // 组件内使用
       <router-link to="/pkproperties">点击跳转</router-link>  // path路径跳转
       <router-link to="{name:'pkproperties',query:{id:1}}">点击跳转</router-link>  // 使用命名路由name跳转
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    传参配置:

     {
       path: '/pkproperties', // 路径
       name:'pkproperties', // 路由名,path路径必写,用name跳转的时候是根据name名找到path进行跳转
       component: () => import('@/views/pkproperties'), // 组件(组件文件名为index的可省略)
       hidden: true
      },
       // 使用命名路由传参,可以传递基本数据类型和数组和对象
       <router-link to="{name:'pkproperties',query:{id:1}}">点击跳转</router-link>  // name名跳转,query传递参数
       <router-link to="{name:'pkproperties',params:{id:1}}">点击跳转</router-link>  // name名跳转,params传递参数
       
       this.$route.query.id // 获取传递的参数(.传递参数的键名)
       this.$route.params.id // 获取传递的参数(.传递参数的键名)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 2.编程式路由跳转(最常用的,不受时机、条件的限制)

    路由配置:

    {
       path: '/pkproperties', // 路径
       name:'pkproperties', // 路由名,path路径必写,用name跳转的时候是根据name名找到path进行跳转
       component: () => import('@/views/pkproperties'), // 组件(组件文件名为index的可省略)
       hidden: true
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    传参配置:

    methods:{
       onSkipTransferParameters(){
       // params传参
            this.$router.push({
               name: "pkproperties",
               params: { 
               name: '小明',
               id: 1,
              },
            });
         onSkipTransferParameters(){
       // query传参
            this.$router.push({
               name: "pkproperties",
               query: { 
               name: '小明',
               id: 1,
              },
            });
       }
     // 获取传递的参数
     this.$route.params.name // 获取就是在当前跳转的组件内调用$route实例,是用params就.params.键名获取值
     this.$route.query.name // 获取就是在当前跳转的组件内调用$route实例,是用query就.query.键名获取值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    query传参在刷新界面后传递的数据不会丢失params传递的参数刷新界面后会丢失参数

    • 3.路由重定向redirect需要用到传参的业务
       { path:"/", redirect: {path:"pkproperties", query:{Pid:'1'}} },
       { path:"pkproperties", component: ()=>import("../views/pkproperties") }
    
    • 1
    • 2

    解决路由重复点击路由沉积的问题

    // 把这段代码直接粘贴到router/index.js中的Vue.use(VueRouter)之前
    const originalPush = VueRouter.prototype.push;
      VueRouter.prototype.push = function (location) {
      return originalPush.call(this, location).catch(err => { })
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意:一定要写在 Vue.use(VueRouter)之前否则无效

    解决路由跳转后不能回到顶部的页面顶部的问题

    在跳转到的组件里配置下面的代码即可

     mounted() {
        /**
         * 路由跳转回到顶部
         */
        // chrome
        document.body.scrollTop = 0;
        // firefox
        document.documentElement.scrollTop = 0;
        // safari
        window.pageYOffset = 0;
      },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    路由导航守卫和案例展示

    • 路由前置导航守卫(beforeEach
        // 全局导航守卫beforeEach
    router.beforeEach((to, from, next) => {
    	// to要到哪个路由去
        // from从哪个路由来
        // next下一步(无论失败与否都要调用,否则会阻止程序继续执行)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    案例1中使用(拦截未登录用户和白名单设置):

    permission.js文件下配置(permission文件最好和main文件在同一目录下创建)

    import router from './router'
    import { getToken } from '@/common/TokenStore'
    
    const whiteList = ['/login', '/register'] // 白名单登录注册界面无需验证Token是否登录直接放行
    
    // 全局导航守卫beforeEach
    router.beforeEach((to, from, next) => {
    	// 白名单中路由直接放行
    	if (whiteList.indexOf(to.path) !== -1) {
    		next()
    		return
    	}
    	// 判断需要登录身份认证的路由
    	const token = getToken() // 获取token
    	if (token) {
    		next()
    	} else {
    		next(`/login`) // 如果登录不存在,重定向到登录界面
    	}
    })
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    main.js文件下引入即可

    import './permission' // 引入即可
    
    • 1

    案例2中使用(设置Tokne失效实现拦截,Tokne失效就导航会登录界面重新登录,未失效就不执行操作)

    login.vue(登录组件登录成功后保存Token和保存获取Token的当前时间戳在本地)

        methods: {
     
          // 登录
          handleLogin() {
            this.$axios.post('/api/Login',{
             username: this.loginForm.username, // 用户名
             password: this.loginForm.password // 密码
            }).then(res => { 
              if(res.data.code != 0) return this.$message.error(res.data.message) // code 不等于0,返回失败的结果,(这的判断参数是根据后端返回的数据进行的,不是固定的)
              if(res.data.code == 0){
                this.$message.success('登录成功')
                // 存储token开始时间
                window.localStorage.setItem('tokenStartTime',new Date().getTime())
                // 存储token
                window.localStorage.setItem('token',res.data.data.token)
                this.$router.push('/home/ks')
              }else {
                this.$message.error('登录失败')
              }
            })
          }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    permission.js(将保存的Token获取时间和当前时间进行一个差值的比较,如果小于我们设定的Token失效时间,就证明登录没有过期可继续访问,如果大于就登录过期Token失效需要重新登录获取。)

    // 导入element提示语的组件可以去element-ui查看用法,这是按需引入的
    import {
        Message
    } from 'element-ui'
     
     
    // 添加请求拦截器
    // 拦截器的第二部分,第一部分在main.js里面
    router.beforeEach((to, from, next) => {
     
      // 获取存储localStorage的token
      let token = window.localStorage.getItem('token')
      // 获取存储token的开始时间
      const tokenStartTime = window.localStorage.getItem('tokenStartTime')
      // 后台给出的token有效时间为一天,这个是后端给的时间以后端为准
      const timeOver = 86400000
      // 获取当前时间
      let date = new Date().getTime()
      // 当前时间减去获取Token的时间如果大于说明是token过期了
      if(date - tokenStartTime > timeOver) {
          token = null // Token过期赋值为null
      }
      // 如果token过期了
      if (!token) {
        if (to.path == '/login') return next()
        // 注意要import element的Message组件
        Message.error("登录状态过期,请重新登录")
        return next('/login')
        // 如果token没有过期,又是选择了登录页面就直接重定向到首页,不需要重新输入账户密码
      } else if (to.path == '/login') {
        return next('/home/ks')
      }
      next()
     
    })
    export default router
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 全局后置守卫(afterEach
    router.afterEach((to,from)=>{})
    
    • 1
    • 组件内守卫(相当于给组件增加生命周期
    beforeRouteEnter 进入组件之前
    beforeRouterEnter(to,from,next){}
    
    beforeRouteUpdate 组件被复用时调用
    beforeRouterUpdate(to,from,next){}
    
    beforeRouteLeave 离开组件时调用
    beforeRouteLeave(to,from,next){}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    访问外部链接

    • vue内部跳转可以通过vue-router中的this.$router.push()和rout-link 来实现,这里在说一下想要访问外部链接的方法

    1.window.location.href = url(不新开一个页面,直接在当前页面跳转)

    methods:{
      onSkip(){
        window.location.href = "http://xxx.xxx.xxx"
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2.window.open(“url”, “_blank”)(打开一个新页面跳转)

    methods:{
      onSkip(){
        window.open("https://xxx.xxx.xxx/", "_blank");
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3.手动创建a标签,然后默认点击

     var a = document.createElement("a");
         a.setAttribute("href", "www.baidu.com");
         a.setAttribute("target", "_blank");
         a.click();
    
    • 1
    • 2
    • 3
    • 4
  • 相关阅读:
    手写本地缓存实战2—— 打造正规军,构建通用本地缓存框架
    nginx 启动、停止、关闭
    Android 基础知识4-2.2常用控件提示(Toast)
    C语言程序设计教程(第三版)李凤霞 第十章课后习题答案
    【图像重建】基于遗传算法实现二值图像重建附matlab代码
    PV操作-同步与互斥
    低度酒赛道进入洗牌期,新品牌如何破局三大难题?
    ADB安装及使用详解
    海洋馆一日游
    做食品能入驻Lazada吗?带你解锁东南亚当地热销及需求食品系列
  • 原文地址:https://blog.csdn.net/AKindofo/article/details/127964154