初识路由

  1. Vue-RouterVue.js 官方的路由管理器;
  2. 它能够创建单页应用 (SPA),通过在应用中创建不同的视图和路径;

基本使用

  1. 定义路由组件

    import Vue from 'vue'
    import VueRouter from 'vue-router'
    import Home from '../views/Home.vue'
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        name: 'Home',
        component: Home
      },
      {
        path: '/about',
        name: 'About',
        // 利用 component 动态引入组件
        component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
        children: [
          {
            // 直接写全或者写 a,不要写 /a
            path: '/about/a',
            component: () => import(/* webpackChunkName: "hello" */ '../views/Hello.vue')
          }
        ]
      }
    ]
    	
    const router = new VueRouter({
      // hash利用的是 onhashchange 事件
      // history利用的是 onpopstate 事件和 pushstate、replaceState 方法
      mode: 'history',
      base: process.env.BASE_URL,
      routes,
      linkActiveClass: 'active',// 重命名全局配置,活跃link
      linkExactActiveClass: 'qq'// 重命名全局配置,精确匹配活跃link
    })
    
    export default router
    
  2. 注册路由

    /* 入口 js */
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      components: { App }, // 映射组件标签
      template: '<App/>', // 指定需要渲染到页面的模板
      router  // 注册路由器
    })
    
  3. 使用路由

    <div>
      <!-- 路由链接 -->
      <router-link to="/about">About</router-link>
      <!-- 用于渲染当前路由组件 -->
      <router-view/>
    </div>
    

动态路由

动态路径参数

同一个路径可以匹配多个路由,路由定义得越早,优先级就越高

  1. router 配置 「/user/:id」/user/foo/user/bar 都将映射到相同的路由 User

    const router = new VueRouter({
      routes: [{
        path: '/user/:id', // 动态路径参数 以冒号开头
        props: true,  // 开启 props,会把 URL 中的参数传递给组件
        component: () => import('@/User.vue'), // 懒加载组件
      },]
    })
    
  2. 获取参数

    <template>
      <div>
        <!-- 方式1: 通过当前路由规则,获取数据 -->
        通过当前路由规则获取:{{ $route.params.id }}
        <br>
        <!-- 方式2(推荐):路由规则中开启 props 传参 -->
        通过开启 props 获取:{{ id }}
      </div>
    </template>
    <script>
      export default {
        name: 'User',
        props: ['id']
      }
    </script>
    
  3. 监控路由参数的变化

    export default {
      // 第一种:使用 watch (监测变化) $route 对象
      watch: {
        $route(to, from) {
          // 对路由变化作出响应...
        }
      },
      // 第二种:使用 2.2 中引入的 beforeRouteUpdate 导航守卫
      beforeRouteUpdate(to, from, next) {
        // don't forget to call next()
      }
    }
    

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

  1. 匹配任意路径,使用通配符 (*),通过 pathMatch 获取通配符参数;

    // 将匹配所有内容并将其放在 `route.params.pathMatch` 下
    // 会匹配所有路径,应该放在最后,通常用于客户端 404 错误
    // 假设访问的 URL 是 /a/b/c,则 route.params.pathMatch = 'a/b/c';
    { path: '/:pathMatch(.*)' },
    
    // 假设访问的 URL 是 /a/b/c,则 route.params.pathMatch = ['a', 'b', 'c'];
    { path: '/:pathMatch(.*)*' },
    
    // 将匹配以 `/user-` 开头的所有内容,并将其放在 `route.params.afterUser` 下
    { path: '/user-:afterUser(.*)' }
    

嵌套路由

  1. 一些应用程序的 UI 由多层嵌套的组件组成;在这种情况下,URL 的片段通常对应于特定的嵌套组件结构,例如:

  2. 配置嵌套路由

    const User = {
      template: `
        <div class="user">
          <!--子路由出口, profile/posts組件 -->
          <router-view/>
        </div>
      `
    }
    
    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
            }
          ]
        }
      ]
    })
    

路由跳转

  1. 使用 <router-link> 创建 a 标签来定义导航链接;

    <router-link : to="{ name: 'user', params: { userId: 123 }}">User</router-link>
    
  2. router.push:会向 history 添加新记录;

    const router = new VueRouter({
      routes: [
        {
          path: '/user/:userId',
          name: 'user', // 设置名称
          component: User
        }
      ]
    });
    
    router.push({ name: 'user', params: { userId: 123 }, query: { name: 'zhangsan' } });
    router.push({ path: '/user', params: { userId: 123 } });
    
  3. router.replace:不会向 history 添加新记录;

  4. router.go(n):在 history 记录中向前或者后退多少步,类似 window.history.go(n)

    // 在浏览器记录中前进一步,等同于 history.forward()
    router.go(1)
    
    // 后退一步记录,等同于 history.back()
    router.go(-1)
    
    // 前进 3 步记录
    router.go(3)
    

重定向、别名

重定向

  1. 重定向是 Vue Router 中的重要功能,允许将一个 URL 自动转向另一个 URL

  2. 静态重定向:

    const routes = [
      {
        path: '/home',
        redirect: '/dashboard' // 访问/home时重定向到/dashboard
      }
    ]
    
  3. 命名路由重定向:

    const routes = [
      {
        path: '/home',
        redirect: { name: 'dashboard' } // 重定向到命名路由
      }
    ]
    
  4. 基于路径参数的重定向:

    const routes = [
      {
        path: '/user/:id',
        redirect: '/profile/:id' // 保留参数
      }
    ]
    
  5. 函数式重定向:

    const routes = [
      {
        path: '/old-path',
        redirect: (to) => {
          // 保留原始查询参数和 hash
          return { path: '/new-path', query: to.query, hash: to.hash };
        }
      }
    ]
    

别名

  1. 别名是 Vue Router 中一个非常有用的功能,它允许你为同一个组件定义多个访问路径,而不会改变浏览器地址栏显示的 URL

  2. 嵌套路由中的别名:

    const routes = [
      {
        path: '/user',
        component: User,
        children: [
          {
            path: 'profile',
            component: Profile,
            alias: ['/me', '/account'] // 嵌套别名
          }
        ]
      }
    ]
    
  3. 带参数的别名:

    const routes = [
      {
        path: '/post/:id',
        component: Post,
        alias: '/article/:id' // 带参数的别名
      }
    ]
    
  4. 绝对路径别名:

    const routes = [
      {
        path: '/admin',
        component: Admin,
        alias: '/root' // 绝对路径别名
      }
    ]
    
  5. 实际应用场景:

    JavaScript
    JavaScript
    JavaScript
    // 场景1:多语言路径
    const routes = [
      {
        path: '/about',
        component: About,
        alias: ['/sobre', '/ueber'] // 西班牙语和德语的别名
      }
    ]
    
    // 场景2:新旧URL并存
    const routes = [
      {
        path: '/new-products',
        component: Products,
        alias: '/legacy-products' // 保持旧URL可用
      }
    ]
    
    // 场景3:简化复杂路径
    const routes = [
      {
        path: '/user/:userId/settings/notifications',
        component: Notifications,
        alias: '/notifications' // 简化路径
      }
    ]
    

别名 VS 重定向

特性 重定向 别名
URL 变化 浏览器地址栏会改变 浏览器地址栏保持不变
历史记录 创建新的导航记录 不创建新的导航记录
实现方式 redirect 属性 alias 属性
典型场景 URL 迁移 同一个组件多个访问路径

路由组件传参

路由组件传参

  1. 通过路由参数传递 (动态路由)

    JavaScript
    HTML
    // 路由配置
    const routes = [
      {
        path: '/user/:id',
        component: User,
        props: true // 启用props传参
      }
    ];
    
    <!-- User.vue 组件 -->
    <template>
      <div>用户ID: {{ id }}</div>
    </template>
    
    <script>
    export default {
      props: ['id'] // 通过props接收参数
    }
    </script>
    
  2. 通过查询参数传递 (?key=value)

    JavaScript
    HTML
    // 路由跳转
    this.$router.push({ path: '/search', query: { q: 'vue' } });
    
    <!-- Search.vue 组件 -->
    <template>
      <div>搜索关键词: {{ $route.query.q }}</div>
    </template>
    
    <script>
    export default {
      created() {
        console.log(this.$route.query.q); // 输出: vue
      }
    }
    </script>
    
  3. 通过 props 传递 (对象模式)

    JavaScript
    HTML
    // 路由配置
    const routes = [
      {
        path: '/promo',
        component: PromoPage,
        props: { newsletterPopup: false } // 静态props
      }
    ]
    
    <!-- PromoPage.vue -->
    <script>
    export default {
      props: {
        newsletterPopup: Boolean
      },
      created() {
        console.log(this.newsletterPopup) // false
      }
    }
    </script>
    
  4. 通过 props 传递 (函数模式)

    JavaScript
    HTML
    // 路由配置
    const routes = [
      {
        path: '/search/:query',
        component: SearchResults,
        props: (route) => ({
          query: route.params.query,
          sort: route.query.sort || 'date'
        })
      }
    ]
    
    <!-- SearchResults.vue -->
    <script>
    export default {
      props: ['query', 'sort'],
      created() {
        console.log(this.query, this.sort)
      }
    }
    </script>
    
  5. 通过 meta 字段传递

    JavaScript
    JavaScript
    // 路由配置
    const routes = [
      {
        path: '/admin',
        component: AdminPanel,
        meta: { requiresAuth: true }
      }
    ]
    
    // 在组件或导航守卫中访问
    this.$route.meta.requiresAuth
    
  6. 通过编程式导航传递 state (Vue Router 4+)

    JavaScript
    JavaScript
    // 跳转时传递state
    this.$router.push({
      name: 'user',
      state: { fromDashboard: true }
    })
    
    // 在目标组件中访问
    this.$route.state.fromDashboard
    

最佳实践对比

传参方式 适用场景 优点 缺点
路由参数 ID 类参数,形成漂亮 URL URL 可收藏,SEO 友好 只能传字符串
查询参数 可选参数,过滤条件 灵活,可传多个 URL 较长
Props 对象 静态配置 类型安全 不能动态变化
Props 函数 需要处理参数的复杂场景 高度灵活 配置稍复杂
Meta 字段 路由元信息,权限控制等 不暴露给用户 不能在组件中响应式更新
State 对象 临时传递大量数据(Vue Router 4+) 不暴露在 URL 上 刷新页面会丢失
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

你好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 初识路由
  2. 2. 基本使用
  3. 3. 动态路由
    1. 3.1. 动态路径参数
    2. 3.2. 捕获所有路由或 404 Not found 路由
  4. 4. 嵌套路由
  5. 5. 路由跳转
  6. 6. 重定向、别名
    1. 6.1. 重定向
    2. 6.2. 别名
    3. 6.3. 别名 VS 重定向
  7. 7. 路由组件传参
    1. 7.1. 路由组件传参
    2. 7.2. 最佳实践对比