快速了解vue路由

11 篇文章 0 订阅
创建一个路由实例的配置选项

使用 new Router 创建了一个新的路由实例,其配置项说明:
mode:路由模式,默认值 ‘hash’ 使用井号( # )作路由,值 ‘history’ 可利用 History API 来完成页面跳转且无须重新加载;
routes:具体的路由配置列表,用到的配置项说明:
path:路由的路径;
name:路由的名称;
component:对应的视图组件;
通过注入路由器,我们可以在任何组件内通过 this. r o u t e r 访 问 路 由 器 , 也 可 以 通 过 t h i s . router 访问路由器,也可以通过 this. router访this.route 访问当前路由
动态路由参数匹配

模式匹配路径$route.params
/user/:username/user/evan{ username: ‘evan’ }
/user/:username/post/:post_id/user/evan/post/123{ username: ‘evan’, post_id: ‘123’ }

除了 r o u t e . p a r a m s 外 , route.params 外, route.paramsroute 对象还提供了其它有用的信息,例如, r o u t e . q u e r y ( 如 果 U R L 中 有 查 询 参 数 ) 、 route.query (如果 URL 中有查询参数)、 route.query(URL)route.hash 等等

相应路由参数的变化

当使用路由参数时,例如从 /user/foo 导航到 /user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用
复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象

const User1 = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 对路由变化作出响应...
    }
  }
}
//或者使用
const User2 = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}
路由匹配优先级

有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高
当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后

嵌套路由
const routes = [
  {
    path:'/user/:id',
    component:()=>import('@/views/user/User'),
    children:[
      {
        //默认子路由
        // UserHome 会被渲染在 User 的 <router-view> 中
        path:'',
        name:'UserHome',
        component:()=>import('@/views/user/UserHome'),
      },
      {
        // 当 /user/:id/profile 匹配成功,
        // UserProfile 会被渲染在 User 的 <router-view> 中
        path:'profile',
        name:'UserProfile',
        component:()=>import('@/views/user/UserProfile'),
      }
    ],
  }
];
编程式的导航
声明式编程式
<router-link :to="…">router.push(…)

在 Vue 实例内部,你可以通过 r o u t e r 访 问 路 由 实 例 。 因 此 你 可 以 调 用 t h i s . router 访问路由实例。因此你可以调用 this. router访this.router.push
router.push这个方法会向 history 栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。

// 字符串
router.push('home')

// 对象
router.push({ path: 'home' })

// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})

// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})

注意:如果提供了 path,params 会被忽略,同样的规则也适用于 router-link 组件的 to 属性
注意: 如果目的地和当前路由相同,只有参数发生了改变 (比如从一个用户资料到另一个 /users/1 -> /users/2),你需要使用 beforeRouteUpdate 来响应这个变化 (比如抓取用户信息)

router.replace 跟 router.push 很像,唯一的不同就是,它不会向 history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录

声明式编程式
<router-link :to="…" replace>router.replace(…)

router.go(n)这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)

命名路由
const router = new VueRouter({
  routes: [
    {
      path: '/user/:userId',
      name: 'user',
      component: User
    }
  ]
})

<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>

router.push({ name: 'user', params: { userId: 123 }})
重定向和路由别名
const router = new VueRouter({
  routes: [
    { 
      path: '/a', 
      redirect: '/b'
    }
  ]
})
const router2 = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' }
  ]
})
//别名的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构
路由组件传参

在组件中使用 $route 会使之与其对应路由形成高度耦合,从而使组件只能在某些特定的 URL 上使用,限制了其灵活性
通过 props 解耦,如果 props 被设置为 true,route.params 将会被设置为组件属性

导航守卫

记住参数或查询的改变并不会触发进入/离开的导航守卫。你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫

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 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。
确保要调用 next 方法,否则钩子就不会被 resolved

全局后置钩子

你也可以注册全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身

router.afterEach((to, from) => {
  // ...
})
路由独享守卫

在路由配置上直接定义 beforeEnter 守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, 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`
  }
}
路由元信息
路由过渡动效
数据获取

有时候,进入某个路由后,需要从服务器获取数据。例如,在渲染用户信息时,你需要从服务器获取用户的数据。我们可以通过两种方式来实现:
导航完成之后获取:先完成导航,然后在接下来的组件生命周期钩子中获取数据。在数据获取期间显示“加载中”之类的指示。
导航完成之前获取:导航完成前,在路由进入的守卫中获取数据,在数据获取成功后执行导航。
从技术角度讲,两种方式都不错 —— 就看你想要的用户体验是哪种。

滚动行为
// 指定滚动行为
  scrollBehavior(to, from, savedPosition) {
    if (to.hash) {
      // 有锚点时,滚动到锚点
      return { selector: to.hash }
    } else if (savedPosition) {
      // 有保存位置时,滚动到保存位置
      return savedPosition
    } else {
      // 默认滚动到页面顶部
      return { x: 0, y: 0 }
    }
  }
路由懒加载
导航守卫

导航守卫分为全局导航守卫和路由导航守卫

router.beforeEach((to, from, next) => {
  /* must call `next` */
})

router.beforeResolve((to, from, next) => {
  /* must call `next` */
})

router.afterEach((to, from) => {})

//组件内的守卫
beforeRouteEnter

beforeRouteUpdate

beforeRouteLeave
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值