vue-router基础知识总结

学习目标:

根据vue-router官网简洁的总结vue-router中的基础知识点,进阶版将会在下一篇文章中发布


动态路由匹配:

routes: [
    // 动态路径参数 以冒号开头
    { path: '/user/:id', component: User }
]

像 /user/foo 和 /user/bar 都将映射到相同的路由。路径参数用:做标记,可以用this.$route.params获取,例如"user/123",获取的params为{id:123},
会出现的问题:如果两个路由映射的是同一个组件的话,vue会就地服用,也就是说该组件的vue实例不会更新,那么自然而然的生命周期函数不会重新执行


捕获所有路由:

此方法可以用来设置404界面,通过通配符*来匹配所有未命中的路由来到指定页面。

{
  // 会匹配所有路径
  path: '*'
}
{
  // 会匹配以 `/user-` 开头的任意路径
  path: '/user-*'
}

但是值得注意的是 当使用通配符路由时,请确保路由的顺序是正确的,也就是说含有通配符的路由应该放在最后。路由 { path: ‘*’ } 通常用于客户端 404 错误。
当使用一个通配符时,$route.params 内会自动添加一个名为 pathMatch 参数。它包含了 URL 通过通配符被匹配的部分:

// 给出一个路由 { path: '/user-*' }
this.$router.push('/user-admin')
this.$route.params.pathMatch // 'admin'
// 给出一个路由 { path: '*' }
this.$router.push('/non-existing')
this.$route.params.pathMatch // '/non-existing'

匹配优先级

有时候,同一个路径可以匹配多个路由,此时,匹配的优先级就按照路由的定义顺序:谁先定义的,谁的优先级就最高。


嵌套路由:

/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User             |                  | User            |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

router-view可以在任意组件中使用,通过配置route的children属性,来达到这种关系

列如
我们在app组件中使用了router-view

<div id="app">
  <router-view></router-view>
</div>
const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

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

我们在User组件也想使用router-view,在User组件内部做路由跳转,那么这种关系如何来描述让vue懂我们的意思呢?使用children属性,提供一个空的子路由来在未匹配到任何children的时候显示

const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的 <router-view> 中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的 <router-view> 中
          path: 'posts',
          component: UserPosts
        }// 当 /user/:id 匹配成功,
        // UserHome 会被渲染在 User 的 <router-view> 中
        { path: '', component: UserHome },
      ]
    }
  ]
})

编程式导航和声明式导航

编程式导航是this.$router.push这种,声明式是<router-link :to="…">这种
router.push方法是往浏览器记录栈中添加一条记录,当你点击<router-link>的时候,会在内部调用router.push方法,所以实际上是一样的

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

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

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

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

注意:如果提供了path,params会被忽略,意思是path不能跟params一起使用,解决方法如下

const userId = '123'
router.push({ name: 'user', params: { userId }}) // -> /user/123
router.push({ path: `/user/${userId}` }) // -> /user/123
// 这里的 params 不生效
router.push({ path: '/user', params: { userId }}) // -> /user

router.replace()跟router.push很像,只不过不会再浏览器记录栈中添加记录
router,go()浏览器前进后退

你也许注意到 router.push、router.replac 和 router.gowindow.history.pushState、 window.history.replaceState 和 window.history.go好像, 实际上它们确实是效仿 window.history API 的。因此,如果你已经熟悉 Browser History APIs,那么在 Vue Router 中操作 history 就是超级简单的。还有值得提及的,Vue Router 的导航方法 (push、 replace、 go) 在各类路由模式 (history、 hash 和 abstract) 下表现一致


命名路由

可以在配置的时候加上name属性

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

通过name进行路由跳转,跟path跳转的时候差不多一个效果,不过用path的时候Params会被忽略,所以用name跳转。

router.push({ name: 'user', params: { userId: 123 }})

命名视图

上面提到了嵌套路由,但是嵌套路由是在一个组件中只有一个router-view中可以,那如果一个组件中需要用多种router-view呢?那么命名视图就派上了用场,实际上就是在router-view上加上name属性,我心思在组件里引入你需要的组件写上不一个效果吗,但是用命名视图的这种方式在很多页面都有相同布局的时候,会比较常用(个人理解),手动狗头

<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>

同时在routes中进行配置,默认是default注意这里用的是components,而不是之前的component

const router = new VueRouter({
  routes: [
    {
      path: '/',
      components: {
        default: Foo,
        a: Bar,
        b: Baz
      }
    }
  ]
})

重定向和别名

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

重定向的目标也可以是命名路由

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

甚至是一个方法,动态返回重定向目标:

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

注意:重定向上的routes如果配置了beforeEnter那么/a不会有任何效果,因为导航首位只到目标路由上。

别名

/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。
“别名”的功能让你可以自由地将 UI 结构映射到任意的 URL,而不是受限于配置的嵌套路由结构。

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

路由组件传参

在我们使用组件的时候,在模板上可能用过{{this.$route.params.id}}这种方式来渲染模板,但这样就会让路由跟对应组件高度耦合,也就是说该组件只能当路由组件用。

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

通过props解耦,让组件可以当普通的组件传递Props那样使用也可以当路由组件使用。

const User = {
  props: ['id'],
  template: '<div>User {{ id }}</div>'
}
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User, props: true },

    // 对于包含命名视图的路由,你必须分别为每个命名视图添加 `props` 选项:
    {
      path: '/user/:id',
      components: { default: User, sidebar: Sidebar },
      props: { default: true, sidebar: false }
    }
  ]
})

这样你便可以在任何地方使用该组件,使得该组件更易于重用和测试。

布尔模式

如果 props 被设置为 true,route.params 将会被设置为组件属性。

对象模式

如果 props 是一个对象,它会被按原样设置为组件属性。当 props 是静态的时候有用。如果不是静态的用下面的函数模式。

const router = new VueRouter({
  routes: [
    { path: '/promotion/from-newsletter', component: Promotion, props: { newsletterPopup: false } }
  ]
})

函数模式

你可以创建一个函数返回 props。这样你便可以将参数转换成另一种类型,将静态值与基于路由的值结合等等。总之这几种方式都是将路由的参数设置为Props,将路由跟对应的视图组件解耦,就不用在created或者mounted里在进行赋值啥的,比如:this.data=this.$route.query.data

const router = new VueRouter({
  routes: [
    { path: '/search', component: SearchUser, props: (route) => ({ query: route.query.q }) }
  ]
})

History 模式

vue-router默认的路由模式是hash模式,是通过’#‘号后面来模拟url来实现路由跳转的,#后面的参数变化页面不会重新加载。
还有一种方式就是通过history方式,他是通过浏览器提供的history.pushState API来实现路由的跳转,它不像hash一样有’#'号,路径就是真实的路径,但是调用api时,不会触发浏览器加载,但是当你刷新浏览器的时候,hash值是不会当作path来发请求的,但是history是实打实的路径,它会带上,那么这时候你后端如果没有处理,命中不到相关资源那么就会404了,所以这里需要处理一下。如果后端没有命中f任何静态资源,那么返回根路径下的静态html。

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

举个nginx的例子,这应该是最常用的了吧,别的例子官网有

location / {
  try_files $uri $uri/ /index.html;
}

如果这样写了,那么你的服务器就永远不会返回404了,所以后端处理没匹配到的路径统一返回静态资源,前端处理没有命中的Path返回404页面,也就是上面提到的用通配符*号来做这种处理,记得要放在最后面,因为优先级是按照你写的顺序来的。

const router = new VueRouter({
  mode: 'history',
  routes: [
    { path: '*', component: NotFoundComponent }
  ]
})

总结

以上是就vue-router总结的基础资料,不过还是建议去看官网,因为这是个人的笔记,有一些地方本人会省略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值