Vue路由重定向、别名与导航守卫

前言

在实际的场景中,当用户访问的是一个页面,但可能出现了一些错误,需要给他呈现另一个页面。或者,当用户的注册状态已经过期,需要跳转到登录页,让用户登录后使用。这些场景下就需要用到路由重定向。别名可以理解为重定向的一种,只不过他的 url 是不改变的,也就是说,表面上的 url 不变,但实际上去的是其他页面。导航守卫可以结合登录来说,例如现在有一个后台管理系统,不登录、非管理人员不予呈现页面。在他访问站点时,先进行登录状态的判断,如果没有登录,则重定向到登录页,其他的页面坚决不可以呈现。这就是导航守卫。

重定向

重定向的实现很简单,只需要在路由表中使用 redirect属性就好:

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' }
  ]
})

redirect后面可以跟路径,也可以跟路由名,甚至可以跟一个函数,函数返回一个路径。但一般直接使用路径,毕竟功能一样的情况下,肯定选择写得最少的那个。

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: { name: 'foo' }}
  ]
})

const router = new VueRouter({
  routes: [
    { path: '/a', redirect: to => {
      // 方法接收 目标路由 作为参数
      // return 重定向的 字符串路径/路径对象
    }}
  ]
})

路由别名

官网描述:/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

尽管表面访问的是 /a,但实际上呈现的页面是/b,不过在路径显示上依然显示/a。别名使用属性 alias 实现。

const router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})

导航守卫

Vue导航守卫这一章节的文档一开头就给我们说:参数的改变并不会触发导航守卫,要想监听路由的变化并做出相应的操作,就必须使用 watch方法或者beforeRouteUpdate()

// watch 方法
watch: {
    // 通过监听路由变化进行数据的更替
    $route(to) {
      if (to.path === '/all') {
        this.filterdTaskList = this.taskList
      } else if (to.path === '/active') {
        this.filterdTaskList = this.taskList.filter(ele => ele.chosen === false)
      } else if (to.path === '/completed') {
        this.filterdTaskList = this.taskList.filter(ele => ele.chosen === true)
      }
    }
  },

// beforeRouteUpdate 方法,其中的代码并不重要,理解怎么用就好
beforeRouteUpdate (to, from, next) {
    if (to.path === '/all') {
        this.filterdTaskList = this.taskList
        next()
      } else if (to.path === '/active') {
        this.filterdTaskList = this.taskList.filter(ele => ele.chosen === false)
        next()
      } else if (to.path === '/completed') {
        this.filterdTaskList = this.taskList.filter(ele => ele.chosen === true)
        next()
      }
  },

全局导航守卫

不过这并不是今天的主题。回到导航守卫,我们前面讲过一点导航守卫的作用:导航守卫在于保护页面,没有权限的用户或者被限制部分权限的用户在访问网站或者某些页面时是不被允许的。一般情况下,大家面临最多的情况是用户未登录或登录过期时需要调用全局导航守卫,直接跳转到登录页面,引导用户进行登录:

// 以下代码写在 router 文件夹下的 index.js 文件中,与路由表 routes 同级
// to,要去的路径;from,来时的路径,一般用不到;next,函数,
// 不调用的话这个守卫钩子不会进行下一步
router.beforeEach((to, from, next) => {
// 判断路径是否是登录页
  if (to.path === '/login') {
// 是登录页,执行下一步
    next();
  } else {
// 不是登录页,判断本地有无 token
    let token = localStorage.getItem('Authorization');
    if (token === null || token === ' ') {
// token 为空或不存在,跳转到登录页
      next('/login');
    } else {
      next();
    }
  }
})

可能还是有人不太懂,对此体会不深,觉得比较飘渺,貌似自己没遇到过。那可以想象以下场景,你在某个人那里得到一个网站的链接,但是这个链接的路径不是网站的首页,而是那个人登录后访问了页面复制给你的链接,这时你打开这个链接,网站检测到你没有登录,便会跳转到登录页。可以拿一个视频网站来试试。

局部导航守卫

既然有全局导航守卫,就会有相应的局部导航守卫。所谓局部,也就是指组件内的导航守卫了。这里的守卫主要是用于监测路由导航到该组件的进程,并在进程中做一些操作,类似于生命周期钩子函数:

const Foo = {
  template: `...`,
  beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不!能!获取组件实例 `this`
    // 因为当守卫执行前,组件实例还没被创建
  },
  beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
    // 可以访问组件实例 `this`
  },
  beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问组件实例 `this`
  }
}

可以看到 beforeRouteUpdate 这个方法,我们在本节开头讲过。三个守卫分别对应导航前、导航中、导航后。beforeRouteUpdate的用法正如前面演示的那样,用于组件内监测路由变化,并做出相应操作。beforeRouteLeave则可以用于禁止用户在还未保存修改前突然离开。

beforeRouteLeave (to, from, next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
// 如果用户确认离开,则离开
  if (answer) {
    next()
  } else {
// 否则取消离开
    next(false)
  }
}

其他的导航守卫这里便不在做演示了,在平时开发中这几个守卫比较常用,有需要有兴趣的同学可以去官网或视频网站找找相关教学。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容