一、入门

我们在已有的 Vue 项目上加入 Vue Router 时,需要做的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲染它们,下面是个简单的例子

1. HTML

  1. <script src="https://unpkg.com/vue@3"></script>
  2. <script src="https://unpkg.com/vue-router@4"></script>
  3. <div id="app">
  4. <h1>Hello App!</h1>
  5. <p>
  6. <!--使用 router-link 组件进行导航 -->
  7. <!--通过传递 `to` 来指定链接 -->
  8. <!--`<router-link>` 将呈现一个带有正确 `href` 属性的 `<a>` 标签-->
  9. <router-link to="/">Go to Home</router-link>
  10. <router-link to="/about">Go to About</router-link>
  11. </p>
  12. <!-- 路由出口 -->
  13. <!-- 路由匹配到的组件将渲染在这里 -->
  14. <router-view></router-view>
  15. </div>
  • router-link:自定义组件 router-link 来创建链接,而不是使用 a 标签
  • router-view:将显示与 url 对应的组件,可以把它放在任何地方,以适应我们的布局

2. JavaScript

  1. // 1. 定义路由组件.
  2. // 也可以从其他文件导入
  3. const Home = { template: '<div>Home</div>' }
  4. const About = { template: '<div>About</div>' }
  5. // 2. 定义一些路由
  6. // 每个路由都需要映射到一个组件。
  7. // 我们后面再讨论嵌套路由。
  8. const routes = [
  9. { path: '/', component: Home },
  10. { path: '/about', component: About },
  11. ]
  12. // 3. 创建路由实例并传递 `routes` 配置
  13. // 你可以在这里输入更多的配置,但我们在这里
  14. // 暂时保持简单
  15. const router = VueRouter.createRouter({
  16. // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
  17. history: VueRouter.createWebHashHistory(),
  18. routes, // `routes: routes` 的缩写
  19. })
  20. // 5. 创建并挂载根实例
  21. const app = Vue.createApp({})
  22. //确保 _use_ 路由实例使
  23. //整个应用支持路由。
  24. app.use(router)
  25. app.mount('#app')
  26. // 现在,应用已经启动了!

通过调用 app.use(router),我们可以在任意组件中以 this.$router 的形式访问它,并且以 this.$route 的形式访问当前路由:

  1. // Home.vue
  2. export default {
  3. computed: {
  4. username() {
  5. // 我们很快就会看到 `params` 是什么
  6. return this.$route.params.username
  7. },
  8. },
  9. methods: {
  10. goToDashboard() {
  11. if (isAuthenticated) {
  12. this.$router.push('/dashboard')
  13. } else {
  14. this.$router.push('/login')
  15. }
  16. },
  17. },
  18. }

要在 setup 函数访问路由,需要调用 useRouteruseRoute 函数,在 Composition API 中可以了解更多信息

二、动态路由匹配

1. 带参数的动态路由匹配规则

用法如下

  1. const User = {
  2. template: '<div>User</div>',
  3. }
  4. // 这些都会传递给 `createRouter`
  5. const routes = [
  6. // 动态字段以冒号开始
  7. { path: '/users/:id', component: User },
  8. ]
  • /users/johnny/users/jolyne 这样的 URL 都会映射到同一个路由

路径参数 用冒号 : 表示。当一个路由被匹配时,它的 params 的值将在每个组件中以 this.$route.params 的形式暴露出来。因此,我们可以通过更新 User 的模板来呈现当前的用户 ID:

  1. const User = {
  2. template: '<div>User {{ $route.params.id }}</div>',
  3. }

可以在同一个路由中设置有多个 路径参数,它们会映射到 $route.params 上的相应字段

匹配模式 匹配路径 $route.params
/users/:username /users/eduardo { username: 'eduardo' }
/users/:username/posts/:postId /users/eduardo/posts/123 { username: 'eduardo', postId: '123' }

除了 $route.params 之外,$route 对象还公开了其他有用的信息,如 $route.query(如果 URL 中存在参数)、$route.hash 等。

2. 响应路由参数的变化

使用带有参数的路由时需要注意的是,当用户从 /users/johnny 导航到 /users/jolyne 时,相同的组件实例将被重复使用
因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。
不过,这也意味着组件的生命周期钩子不会被调用。

要对同一个组件中参数的变化做出响应的话,你可以简单地 watch $route 对象上的任意属性,在这个场景中,就是 $route.params

  1. const User = {
  2. template: '...',
  3. created() {
  4. this.$watch(
  5. () => this.$route.params,
  6. (toParams, previousParams) => {
  7. // 对路由变化做出响应...
  8. }
  9. )
  10. },
  11. }

或者,使用 beforeRouteUpdate 导航守卫,它也可以取消导航:

  1. const User = {
  2. template: '...',
  3. async beforeRouteUpdate(to, from) {
  4. // 对路由变化做出响应...
  5. this.userData = await fetchUser(to.params.id)
  6. },
  7. }

3. 捕获所有路由或 404 Not found 路由

常规参数只匹配 url 片段之间的字符,用 / 分隔。如果我们想匹配任意路径,我们可以使用自定义的 路径参数 正则表达式,在 路径参数 后面的括号中加入 正则表达式 :

  1. const routes = [
  2. // 将匹配所有内容并将其放在 `$route.params.pathMatch` 下
  3. { path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
  4. // 将匹配以 `/user-` 开头的所有内容,并将其放在 `$route.params.afterUser` 下
  5. { path: '/user-:afterUser(.*)', component: UserGeneric },
  6. ]

在这个特定的场景中,我们在括号之间使用了自定义正则表达式,并将 pathMatch 参数标记为可选可重复。这样做是为了让我们在需要的时候,可以通过将 path 拆分成一个数组,直接导航到路由:

  1. this.$router.push({
  2. name: 'NotFound',
  3. params: { pathMatch: this.$route.path.split('/') },
  4. })

4. 高级匹配模式

Vue Router 使用自己的路径匹配语法,其灵感来自于 express,因此它支持许多高级匹配模式,如可选的参数,零或多个 / 一个或多个,甚至自定义的正则匹配规则。请查看高级匹配文档来探索它们。

三、未完待续…

参考链接

基础:https://router.vuejs.org/zh/guide/