温故而知新之Vue Router

动态路由匹配

{path: '/user/:id', component: User}

this.$route.params

响应路由参数的变化

路由跳转时,原来的组件实例会被复用,这意味着组件的生命周期钩子并不会再被调用
复用组件时,想对路由参数的变化做出响应的话,可以watch $route对象

const User = {
  template: '...',
  watch: {
    '$route'(to, from ){
      // 做出响应
    }
  }
}

或者使用 2.2中引入的 导航守卫 beforeRouteUpdate

const User = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

嵌套路由

使用children

const router = new VueRouter({
    routes: [{
      path: '/user/:id',
      component: User,
      children: [
        {path: '', component: UserHome}
      ]
  }]
})

编程式的导航

router.push(location, onComplete?, onAbort?)
2.2.0+提供了onComplete/onAbort回调函数,在导航成功完成或终止后调用
注意:在 Vue 实例内部,你可以通过 router 访问路由实例。因此你可以调用 this.router.push。
这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL
#声明式

<router-link :to="..."> 

#编程式

router.push(...)
router.push('home') //字符串
router.push({path:'home'}) // 对象
router.push({name: 'user',params: {userId: 123}})
router.push({path: 'register', query: {plan: 'private'}})
router.push({path: `/user/${userId}` }) // /user/123

router.replace(location, onComplete?, onAbort?)
跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录。
#声明式

<router-link :to="..." replace> 

#编程式

router.replace(...)

router.go(n)
类似 window.history.go(n)

命名路由

name

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,这个时候命名视图就派上用场了

<router-view name="a"></router-view>
<router-view ></router-view>  // 没有设置名字,默认为default
const router = new VueRouter({
    routes: [
      {
        path; '/',
        components:{
            default:Foo,
            b:Baz
          }
      }
  ]
})
重定向和别名
const router = new VueRouter({
    routes: [
      {
        path: '/a', redirect: '/b'
      },
      {path: '/a', redirect: {name: 'foo'}},
      {path: '/a',redirect: to=> {
          // 方法接收 目标路由 作为参数
          // return 重定向的 字符串路径/路径对象
      }}
  ]
})

注意: 导航守卫并没有应用在跳转路由上,而仅仅应用在其目标上

别名
routes: [
  // 访问 /b,url会保持/b,但是匹配路由为/a,
  {path: '/a', component: A, alias: '/b'}
]
路由组件传参

在组件中使用$route会使之与对应路由形成高度耦合,从而使组件只能在某些特定的URL上使用,使用props组件和路由解藕

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User }
  ]
})

通过props解藕

const User = {
  props: ['id'],
  template: '<div>User{{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    {path: 'user/id', component: User, props: true}, // props设置为true,route.params 将会被设置为组件属性
    // 命名视图的路由
    { path: '/user/:id',
      components: {default: User, siderbar: sidebar},
      porps: {default: true, sidebar: false}
    }
  ]
})
HTML5 History 模式

vue-router默认hash模式,使用URL的hash来模拟一个完整的URL,当URL改变,页面不会重新加载(配合onhashchange事件)
history模式,利用history.pushState API来完成URL跳转而无须重新加载页面

new VueRouter({
  mode: 'history',
  routes: [...]
})

history模式,需要后台配置支持

导航守卫

参数或查询的改变并不会触发进入/离开的导航守卫,组件会复用,可以通过watch $route对象或使用 beforeRouteUpdate 的组件内守卫

全局守卫

router.beforeEach 全局前置守卫

const router = new VueRouter({...})
router.beforeEach((to, from ,next)=>{
//...
})
  • to: Route: 即将要进入的目标路由对象
  • from: Route: 当前导航正要离开的路由
  • next:Function 一定要调用该方法来resolve这个钩子,执行效果依赖 next 方法的调用参数
    next():进行管道中的下一个钩子,如果全部钩子执行完了,则导航的状态就是confirmed(确认的)
    next(false):中断当前 的导航,如果浏览器的URL改变了(可能是用户手动 或浏览器后退),那么URL地址会重置到from路由对应的地址
    next('/')或者next({path: '/'}):跳转到一个不同的地址,当前的导航被中断,然后 进行一个新的导航
    next(error) 2.4.0+ 如果传入 的是一个error实例,则导航会被中止且该错误会被传递给router.onError()注册过的回调

#全局解析守卫
2.5.0新增
router.beforeResolve
#全局后置钩子

router.afterEach((to,from)=>{
// 没有next
})

路由独享的守卫

写在路由中

const router = new VueRouter({
  routes: [{
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next){
      ...
      }
  }]
})

组件内的守卫

  • beforeRouteEnter 不!能!获取组件实例 this
beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}
  • beforeRouteUpdate 2.2新增 // 在当前路由改变,但是该组件被复用时调用
  • beforeRouteLeave
    #完整的导航解析流程
    导航被触发——组件中调用 beforeRouteLeave——全局beforeEach——在重用的组件里调用beforeRouteUpdate——路由配置的beforeEnter——解析异步路由组件——被激活的组件调用beforeRouteEnter——全局的beforeResolve——导航被确认——调用全局的afterEach——触发DOM更新——调用beforeRouteEnter中给next的回调函数

路由元信息

meta
一个路由匹配到的所有路由记录会暴露为 route 对象 (还有在导航守卫中的路由对象) 的route.matched 数组

// 在全局导航守卫中检查元字段
router.beforeEach((to, from,next)=>{
    if(to.matched.some(record => record.meta.requiresAuth)){
    next()
    }
})

过渡动效

<transition :name='name'>
  <router-view></router-view>
</transition>
``

watch: {
'$route' (to, from){
...
}
}

###数据获取
- 导航完成之后获取
 在created钩子函数中获取
- 导航完成之前获取
在组件 beforeRouteEnter中获取数据,获取成功调用 next()方法
###滚动行为
注意: 这个功能只在支持 history.pushState 的浏览器中可用。

const router = new VueRouter({
routes: [],
scrollBehavior(to, from , savedPositon){
// return 期望滚动到哪个位置
//{ x: number, y: number }
}
})

第三个参数 savedPosition 当且仅当 popstate 导航 (通过浏览器的 前进/后退 按钮触发) 时才可用。
###路由懒加载

const Foo = ()=>import('./Foo.vue')

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

推荐阅读更多精彩内容

  • Vue Router API 解析顺序 页面A 跳转到页面 BA的beforeRouteLeave=>main.j...
    lmmy123阅读 320评论 0 0
  • 回忆: 我们知道,h5的history或者hash帮助我们解决了,变化url跳转页面不发送请求,并且我们能监听到u...
    LoveBugs_King阅读 3,650评论 0 5
  • 前言 vue-router是什么:是vue.js官方的路由管理器和vue.js的核心深度的集成,让开发者更加简单的...
    GUAN_one阅读 3,716评论 0 2
  • 学习目的 学习Vue的必备技能,必须 熟练使用 Vue-router,能够在实际项目中运用。 Vue-rout...
    _1633_阅读 92,193评论 3 58
  • 用Vue.js + vue-router创建单页应用,是非常简单的,基本是这样的: 组件 → 路由 → 渲染地方 ...
    阿go阅读 1,399评论 0 0