Vue Router API 参考:常用方法与属性详解

Vue Router API 参考:常用方法与属性详解

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用 (SPA) 变得易如反掌。本文将深入探讨 Vue Router 的常用 API,包括方法和属性,并通过示例代码进行详细讲解,帮助你全面掌握 Vue Router 的使用。

一、核心概念回顾

在深入 API 之前,让我们快速回顾几个 Vue Router 的核心概念:

  • 路由 (Route):一个路由就是一个 URL 路径与一个 Vue 组件之间的映射关系。例如,/home 映射到 Home 组件,/about 映射到 About 组件。
  • 路由器 (Router):路由器负责管理所有的路由,监听 URL 变化,并根据路由配置渲染相应的组件。
  • 路由配置 (Router Configuration):一个 JavaScript 对象,定义了所有路由的映射关系、导航守卫、滚动行为等。
  • 路由出口 (Router View)<router-view> 组件,用于在父组件中渲染当前路由匹配到的子组件。
  • 路由链接 (Router Link)<router-link> 组件,用于创建导航链接,用户点击后会触发路由跳转,而不会导致整个页面刷新。

二、$router 对象(路由器实例)

$router 对象是 Vue Router 的路由器实例,它可以在任何 Vue 组件中通过 this.$router 访问。$router 对象提供了许多方法和属性,用于编程式导航、访问路由信息等。

2.1 常用方法

2.1.1 push(location, onComplete?, onAbort?)

  • 功能:以编程方式导航到一个新的 URL。类似于 history.pushState,它会在浏览器的历史记录中添加一条新记录。
  • 参数
    • location: 目标路由。可以是一个字符串路径,也可以是一个描述路由的对象(包含 pathnameparamsquery 等属性)。
    • onComplete: 可选的回调函数,当导航成功完成时调用。
    • onAbort: 可选的回调函数,当导航被中断(例如,被导航守卫阻止)时调用。
  • 返回值: 一个 Promise 对象(如果支持 Promise),解析为成功或失败。
  • 示例

    ```javascript
    // 字符串路径
    this.$router.push('/home');

    // 带有路径的对象
    this.$router.push({ path: '/user/123' });

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

    // 带查询参数
    this.$router.push({ path: '/products', query: { sort: 'price' } });

    // 使用回调
    this.$router.push('/profile', () => {
    console.log('导航完成');
    }, (err) => {
    console.error('导航失败', err);
    });

    //Promise
    this.$router.push('/login')
    .then(() => {
    //导航成功
    }).catch(err => {
    //失败的处理
    });
    ```

2.1.2 replace(location, onComplete?, onAbort?)

  • 功能:与 push 类似,但它会替换当前的历史记录条目,而不是添加新的条目。类似于 history.replaceState
  • 参数:与 push 相同。
  • 返回值: 一个 Promise 对象(如果支持 Promise),解析为成功或失败。
  • 示例

    javascript
    this.$router.replace({ name: 'login' });

2.1.3 go(n)

  • 功能:在浏览器的历史记录中前进或后退 n 步。类似于 history.go(n)
  • 参数
    • n: 整数,表示要前进(正数)或后退(负数)的步数。
  • 示例

    ```javascript
    // 后退一页
    this.$router.go(-1);

    // 前进一页
    this.$router.go(1);

    // 前进两页
    this.$router.go(2);
    ```

2.1.4 back()

  • 功能:后退一页。等同于 this.$router.go(-1)
  • 示例

    javascript
    this.$router.back();

2.1.5 forward()

  • 功能:前进一页。等同于 this.$router.go(1)
  • 示例

    javascript
    this.$router.forward();

2.1.6 addRoute(route, parent?)

  • 功能: 动态添加一个新的路由。
  • 参数:
    • route: 一个符合路由配置格式的对象。
    • parent? (可选): 父路由的名称或路径。如果提供,新路由将作为该父路由的子路由。
  • 返回值: 一个函数,调用该函数可以删除添加的路由。
  • 示例:
    ```javascript
    const removeRoute = this.$router.addRoute({
    path: '/new-route',
    name: 'NewRoute',
    component: NewRouteComponent
    });

    // 移除添加的路由
    removeRoute();

    // 添加子路由
    this.$router.addRoute({
    path: '/parent',
    name: 'Parent',
    component: ParentComponent
    }, { path: 'child', name: 'Child', component: ChildComponent });
    ```

2.1.7 removeRoute(name)

  • 功能: 根据路由名称移除一个已存在的路由。
  • 参数:
    • name: 要移除的路由的名称。
  • 示例:
    javascript
    this.$router.removeRoute('NewRoute'); // 移除名为 'NewRoute' 的路由

2.1.8 hasRoute(name)

  • 功能:检查是否存在指定名称的路由
  • 参数:
    • name: 要检查的路由的名称
  • 返回值: boolean
  • 示例:
    javascript
    if (this.$router.hasRoute('User')) {
    //路由'User' 存在
    }

2.1.9 getRoutes()

  • 功能: 获取当前所有激活的路由记录的列表。
  • 返回值: Array<RouteRecord>
  • 示例:
    javascript
    const routes = this.$router.getRoutes();
    console.log(routes); //输出当前所有路由信息

2.2 常用属性

2.2.1 currentRoute

  • 类型Route 对象 (响应式)
  • 功能:表示当前激活的路由信息。它是一个响应式对象,当路由变化时,依赖于它的组件会重新渲染。
  • 包含的属性
    • path: 当前路由的完整路径(例如,/user/123?name=john)。
    • name: 路由的名称(如果有)。
    • params: 路由参数对象(例如,{ userId: 123 })。
    • query: 查询参数对象(例如,{ name: 'john' })。
    • hash: URL 的哈希部分(例如,#section1)。
    • fullPath: 完整的解析后的 URL,包含查询参数和哈希(例如,/user/123?name=john#section1)。
    • matched: 一个数组,包含当前路由匹配到的所有路由记录(从父到子)。
    • meta: 路由元信息对象(如果有)。
    • redirectedFrom: 如果当前路由是被重定向来的,则该属性包含原始路由的信息.
  • 示例

    vue
    <template>
    <div>
    <p>当前路径:{{ $router.currentRoute.path }}</p>
    <p>用户 ID:{{ $router.currentRoute.params.userId }}</p>
    <p>查询参数:{{ $router.currentRoute.query }}</p>
    </div>
    </template>

2.2.2 options

  • 类型RouterOptions
  • 功能: 返回传递给 new VueRouter() 构造函数的原始选项对象. 包含了 routes , mode, base 等.
  • 示例:
    javascript
    console.log(this.$router.options); //输出创建路由器时传入的配置

2.2.3 app

  • 类型: Vue
  • 功能: 当前的 Vue 根实例.
  • 示例:
    javascript
    console.log(this.$router.app); //输出Vue 根实例

三、$route 对象 (当前路由信息)

$route 对象与 $router.currentRoute 相同,它也代表当前激活的路由信息。你可以在组件中通过 this.$route 访问它。$route 是响应式的,当路由变化时,依赖于它的组件会自动更新。

注意: this.$routethis.$router.currentRoute 是同一个对象的不同引用方式.

$route 对象的属性与 $router.currentRoute 完全一致,包括:pathnameparamsqueryhashfullPathmatchedmeta, redirectedFrom

示例

```vue

```

四、路由配置选项

在创建 Vue Router 实例时,我们需要提供一个配置对象。这个对象定义了路由的映射关系、导航守卫、滚动行为等。

4.1 routes

  • 类型Array<RouteConfig>
  • 功能:定义路由映射关系。每个 RouteConfig 对象描述一个路由。
  • RouteConfig 对象的属性

    • path: 字符串,路由的路径。
    • name: 字符串,路由的名称(可选,但推荐使用,方便编程式导航)。
    • component: 组件,当路由匹配时要渲染的组件。可以是一个组件对象,也可以是一个返回组件的函数(用于代码分割)。
    • components: 对象,用于命名视图。当一个路由需要渲染多个组件时使用。
    • redirect: 字符串、对象或函数,重定向到另一个路由。
    • props: 布尔值、对象或函数,将路由参数作为 props 传递给组件。
    • alias: 字符串或数组,路由别名。
    • children: 数组,嵌套路由配置。
    • meta: 对象,路由元信息(自定义数据)。
    • beforeEnter: 导航守卫函数,只对当前路由生效。
    • caseSensitive: 布尔值, 匹配规则是否大小写敏感?(默认值:false)
    • pathToRegexpOptions: 编译正则的选项: 更多信息.
  • 示例

    javascript
    const routes = [
    {
    path: '/',
    name: 'home',
    component: Home,
    },
    {
    path: '/about',
    name: 'about',
    component: () => import('./views/About.vue'), // 懒加载
    },
    {
    path: '/user/:userId',
    name: 'user',
    component: User,
    props: true, // 将 params 作为 props 传递给 User 组件
    meta: { requiresAuth: true }, // 自定义元信息
    },
    {
    path: '/posts/:postId',
    components: {
    default: Post,
    sidebar: PostSidebar
    }
    },
    {
    path: '/login',
    name: 'login',
    component: Login,
    beforeEnter: (to, from, next) => {
    // 只对 /login 路由生效的守卫
    if (isAuthenticated()) {
    next('/'); // 如果已登录,重定向到首页
    } else {
    next(); // 允许访问 /login
    }
    },
    },
    {
    path: '/parent',
    component: Parent,
    children: [
    {
    path: 'child1', //相对于 /parent
    component: Child1
    },
    {
    path: '/absolute-child', //绝对路径
    component: AbsoluteChild
    }
    ]
    },
    {
    path: '/order',
    redirect: '/order/pending' //重定向
    },
    {
    path: '*', //通配符 * 匹配任何路径
    component: NotFound
    }
    ];

4.2 mode

  • 类型string
  • 可选值
    • 'history': 使用 HTML5 History API,需要服务器配置支持。
    • 'hash': 使用 URL 的哈希部分 (#) 来模拟路由,不需要服务器配置。
    • 'abstract': 在非浏览器环境中使用 (例如 Node.js).
  • 默认值'hash'
  • 示例

    javascript
    const router = new VueRouter({
    mode: 'history', // 使用 history 模式
    routes,
    });

4.3 base

  • 类型string
  • 功能:应用的基路径。例如,如果整个单页应用服务在 /app/ 下,那么 base 就应该设为 "/app/"
  • 默认值'/'
  • 示例

    javascript
    const router = new VueRouter({
    base: '/my-app/',
    routes,
    });

4.4 linkActiveClass

  • 类型string
  • 功能:全局配置 <router-link> 的默认激活 class。
  • 默认值'router-link-active'
  • 示例

    javascript
    const router = new VueRouter({
    linkActiveClass: 'active-link',
    routes,
    });

4.5 linkExactActiveClass

  • 类型string
  • 功能:全局配置 <router-link> 的精确激活 class(只有当 URL 与 <router-link>to 属性完全匹配时才添加)。
  • 默认值'router-link-exact-active'
  • 示例:
    javascript
    const router = new VueRouter({
    linkExactActiveClass: 'exact-active'
    });

4.6 scrollBehavior

  • 类型(to, from, savedPosition) => Position | { x: number, y: number } | { selector: string, offset?: { x: number, y: number } } | Promise<PositionResult>
  • 功能:自定义路由切换时的滚动行为。
  • 参数
    • to: 即将进入的目标路由对象。
    • from: 即将离开的源路由对象。
    • savedPosition: 仅当使用浏览器的前进/后退按钮时才可用,表示之前滚动的位置。
  • 返回值
    • { x: number, y: number }: 滚动到指定的坐标。
    • { selector: string, offset?: { x: number, y: number } }: 滚动到指定的元素,可以使用 offset 调整偏移量。
    • Promise<PositionResult>: 异步滚动.
    • false 或 空对象: 不发生滚动.
  • 示例

    ```javascript
    const router = new VueRouter({
    routes,
    scrollBehavior(to, from, savedPosition) {
    if (savedPosition) {
    return savedPosition; // 使用浏览器历史记录的滚动位置
    } else if (to.hash) {
    return { selector: to.hash }; // 滚动到锚点
    } else {
    return { x: 0, y: 0 }; // 滚动到页面顶部
    }

    // 异步滚动
    // return new Promise((resolve) => {
    //  setTimeout(() => {
    //   resolve({x: 0, y: 0});
    //  }, 500);
    // });
    

    },
    });
    ```

4.7 parseQuery / stringifyQuery

  • 类型: Function
  • 功能: 自定义查询字符串的解析和序列化函数。
  • 示例:
    javascript
    const router = new VueRouter({
    parseQuery(query) {
    // 自定义解析逻辑
    },
    stringifyQuery(query) {
    //自定义序列化
    }
    })

4.8 fallback

  • 类型: boolean
  • 功能: 当浏览器不支持 history.pushState 控制路由是否应该回退到 hash 模式。默认值为 true
    在 IE9 中, 如果设置为 false,则在 mode: 'history' 下,所有 router-link 导航都会触发整页刷新。
  • 示例:
    javascript
    const router = new VueRouter({
    mode: 'history',
    fallback: false //IE9 下禁用回退
    });

五、导航守卫

导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的。

5.1 全局守卫

  • beforeEach(to, from, next):在每次导航前执行。
  • beforeResolve(to, from, next):在每次导航前执行,但在 beforeEach 之后,所有组件内守卫和异步路由组件被解析之后。
  • afterEach(to, from):在每次导航完成后执行(没有 next 参数)。

    ```javascript
    router.beforeEach((to, from, next) => {
    // to: 即将进入的目标路由对象
    // from: 即将离开的源路由对象
    // next: 函数,必须调用,否则导航不会继续
    // - next(): 继续导航
    // - next(false): 中断导航
    // - next('/login'): 重定向到 /login
    // - next(new Error('...')): 抛出错误

    if (to.matched.some(record => record.meta.requiresAuth)) {
    //判断是否需要登录权限
    if (!isAuthenticated()) {
    next({ name: 'Login', query: { redirect: to.fullPath } }) //未登录,跳转到登录页面
    } else {
    next(); //已经登录
    }
    }else {
    next(); //确保一定要调用 next()
    }
    });

    router.beforeResolve((to, from, next) => {
    //类似 beforeEach,区别是在所有组件内守卫和异步路由组件被解析之后
    next();
    });

    router.afterEach((to, from) => {
    // to: 已经进入的目标路由对象
    // from: 已经离开的源路由对象
    console.log('导航完成', to, from);
    //常用于埋点统计
    });
    ```

5.2 路由独享守卫

  • beforeEnter(to, from, next):在单个路由配置中定义,只对该路由生效。

    javascript
    const routes = [
    {
    path: '/profile',
    component: Profile,
    beforeEnter: (to, from, next) => {
    // ...
    },
    },
    ];

5.3 组件内守卫

  • beforeRouteEnter(to, from, next):在渲染该组件的对应路由被 confirm 前调用。不能访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。
  • beforeRouteUpdate(to, from, next):在当前路由改变,但是该组件被复用时调用。可以访问 this
  • beforeRouteLeave(to, from, next):导航离开该组件的对应路由时调用。可以访问 this

    vue
    <script>
    export default {
    beforeRouteEnter(to, from, next) {
    // 在渲染该组件的对应路由被 confirm 前调用
    // 不能访问 `this`
    next(vm => {
    // 通过 `vm` 访问组件实例
    console.log(vm);
    });
    },
    beforeRouteUpdate(to, from, next) {
    // 在当前路由改变,但是该组件被复用时调用
    // 可以访问 `this`
    next();
    },
    beforeRouteLeave(to, from, next) {
    // 导航离开该组件的对应路由时调用
    // 可以访问 `this`
    const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
    if (answer) {
    next()
    } else {
    next(false)
    }
    },
    };
    </script>

六、<router-link> 组件

<router-link> 是 Vue Router 提供的用于创建导航链接的组件。它会被渲染成一个 <a> 标签,但它会阻止浏览器的默认跳转行为,而是通过 Vue Router 来进行路由切换。

6.1 常用属性

  • to:目标路由。可以是字符串路径,也可以是一个描述路由的对象。
  • replace:布尔值,如果设置为 true,则使用 replace 方式导航,而不是 push
  • append:布尔值,如果设置为true,则在当前 (相对) 路径附加其路径。例如,我们从 /a 导航到一个相对路径 b,如果没有配置 append,则路径为 /b,如果配了,则为 /a/b
  • tag:字符串,指定要渲染的标签,默认为 'a'
  • active-class:字符串,当链接激活时应用的 class,默认为 'router-link-active'
  • exact:布尔值,是否使用精确匹配模式。
  • exact-active-class:字符串,当链接精确激活时应用的 class,默认为 'router-link-exact-active'
  • event: 字符串或数组, 声明可以触发导航的事件。默认是 'click'.
  • aria-current-value: 当链接根据路由匹配规则激活时要使用的 aria-current 的值。

  • 示例

    vue
    <router-link to="/">Home</router-link>
    <router-link :to="{ name: 'user', params: { userId: 123 } }">User</router-link>
    <router-link to="/about" replace>About</router-link>
    <router-link to="/contact" tag="li">Contact</router-link>
    <router-link to="/news" active-class="is-active">News</router-link>
    <router-link to="/posts/123" exact>Post 123</router-link>
    <router-link to="/events" :event="['mousedown', 'touchstart']">Events</router-link>

七、<router-view> 组件

<router-view> 是一个占位符,用于渲染当前路由匹配到的组件。

7.1 常用属性

  • name:字符串, 如果 <router-view>设置了名称,则会渲染对应的路由配置中 components 下的相应组件。
  • 示例:
    ```vue



    javascript
    //路由配置
    {
    path: '/posts/:postId',
    components: { //注意是复数 components
    default: Post,
    sidebar: PostSidebar
    }
    }
    ```

八、总结

本文详细介绍了 Vue Router 的常用 API,包括 $router 对象的方法和属性、$route 对象、路由配置选项、导航守卫、<router-link> 组件和 <router-view> 组件。通过掌握这些 API,你可以灵活地控制路由、实现各种导航需求,构建功能强大的单页面应用。

希望这篇文章能够帮助你更好地理解和使用 Vue Router! 请记住,熟练掌握 Vue Router 的关键在于实践。多写代码,多尝试不同的配置和用法,你会越来越熟练。

THE END