Skip to content

VueRouter

[TOC]

索引

HTML5

History

  • history.lengthnumber只读,返回一个表示会话历史中的条目数量的整数,包括当前加载的页面。
  • history.stateState,用于访问/操作浏览器历史记录中的状态对象。主要用于SPA中的导航操作。
  • history.back()(),用于让浏览器回到历史记录中的前一个页面。可理解为模拟用户点击浏览器的“后退”按钮。
  • history.forward()(),用于让浏览器前进到历史记录中的下一个页面。可理解为模拟用户点击浏览器的“前进”按钮。
  • history.go()(delta),用于在浏览器历史记录栈中进行前进或后退操作。
  • history.pushState()(state,title?,url?),用于将一个新的历史记录条目添加到浏览器的历史记录栈中,而不会刷新页面。
  • history.replaceState()(state,title?,url?),用于替换当前浏览器历史记录中的条目。
  • onpopstate(event)=>void,是一个浏览器的事件监听器,用于监听浏览器历史记录的变化。

HTML5

History

length

history.lengthnumber只读,返回一个表示会话历史中的条目数量的整数,包括当前加载的页面。

state

history.stateState,用于访问/操作浏览器历史记录中的状态对象。主要用于SPA中的导航操作。

  • 返回:
  • stateState | null,返回当前页面的状态对象。如果没有则返回null。

back()

history.back()(),用于让浏览器回到历史记录中的前一个页面。可理解为模拟用户点击浏览器的“后退”按钮。

forward()

history.forward()(),用于让浏览器前进到历史记录中的下一个页面。可理解为模拟用户点击浏览器的“前进”按钮。

go()

history.go()(delta),用于在浏览器历史记录栈中进行前进或后退操作。

  • deltanumber,表示在浏览器历史记录栈中的偏移量。
    • 正数:浏览器会前进delta个页面。
    • 负数:浏览器会后退delta个页面。
    • 0:浏览器会刷新当前页面。
    • 超出范围:超出历史栈的范围,浏览器不会做任何跳转,页面保持不变。

pushState()

history.pushState()(state,title?,url?),用于将一个新的历史记录条目添加到浏览器的历史记录栈中,而不会刷新页面。

  • stateobject,包含有关该历史条目的信息的对象。

  • title?string,新的历史记录条目的标题。很少用到,常设为""

  • url?string,新的历史记录条目的 URL。必须是同一域名下的有效路径。

  • 示例:

    • 基本用法
    js
    // state 对象包含当前视图的信息
    const state = { page: 1 };
    const title = "";  // 通常是空字符串
    const url = "/page1";
    
    // 将新的历史记录条目添加到浏览器历史记录栈
    history.pushState(state, title, url);
    • 结合popstate 事件
    js
    // 监听 popstate 事件
    window.addEventListener("popstate", function(event) {
      console.log("State changed:", event.state);
      // 根据新的 state 进行页面更新
      updatePageView(event.state.section);
    });
    
    // 通过 pushState 改变历史记录
    history.pushState({ section: "home" }, "", "/home");
    
    // 模拟用户点击浏览器的后退按钮
    history.back();

replaceState()

history.replaceState()(state,title?,url?),用于替换当前浏览器历史记录中的条目。

  • stateobject,包含有关该历史条目的信息的对象。

  • title?string,新的历史记录条目的标题。很少用到,常设为""

  • url?string,新的历史记录条目的 URL。必须是同一域名下的有效路径。

  • 特性:

    • 对比pushState()
      • pushState()会添加新的历史记录条目,会增加一个新的条目。
      • replaceState()会替换当前历史记录条目,不会改变历史栈的长度。
  • 示例:

    • 替换当前历史记录的URL
    js
    // 当前 URL 是 "/page1",我们想将它替换为 "/page2"
    const state = { page: 2 };
    const title = "";
    const url = "/page2";
    
    // 替换当前的历史记录条目
    history.replaceState(state, title, url);
    • 结合popstate 事件
    js
    // 监听 popstate 事件
    window.addEventListener("popstate", function(event) {
      console.log("State changed:", event.state);
      // 根据新的 state 进行页面更新
      updatePageView(event.state.section);
    });
    
    // 替换历史记录
    history.replaceState({ section: "home" }, "", "/home");

onpopstate

onpopstate(event)=>void,是一个浏览器的事件监听器,用于监听浏览器历史记录的变化。

  • event{type,target,state},事件触发时传递的event对象。
    • stateobject,与当前历史条目相关联的状态对象。
  • 语法:
    • 触发条件:当用户通过浏览器的“后退”/“前进”按钮导航,或通过 pushState()/replaceState() 方法修改历史记录时触发。

VueRouter

组件

<router-link>to replace? custom? active-class? exact-active-class? v-slot?,是 Vue Router 的导航组件,用于在SPA中生成可点击的路由链接,默认渲染为a标签。核心作用是实现无刷新页面切换,并自动处理路由激活状态。

  • tostring|object,指定目标路由的路径或路由对象。

  • replace?boolean默认:false,导航时替换当前历史记录。

  • custom?boolean默认:false,禁用默认a标签渲染,完全自定义内容,需手动实现路由跳转。

  • active-class?string默认:router-link-active,当目标路由是当前路由的子路径时激活 CSS 类名。

  • exact-active-class?string默认:router-link-exact-active,仅当目标路由与当前路由完全匹配时激活 CSS 类名。

  • v-slot?{href?,route?,navigate?,isActive?,isExactActive?},通过 v-slot 可完全自定义链接内容和行为。

    • href?string,解析后的 URL,可用于原生a标签。
    • route?object,解析后的规范化路由对象。
    • navigate?function,触发导航的函数。
    • isActive?boolean,是否匹配当前路由。
    • isExactActive?boolean,是否严格匹配当前路由。
  • 语法:

    • 参数to的类型

      • 字符串形式
      html
      <router-link to="/home">首页</router-link>
      • 对象形式:动态路径或带参数。
      html
      <router-link :to="{ path: '/user', query: { id: 1 } }">用户</router-link>
      <!-- 结果:/user?id=1 -->
      
      <router-link :to="{ name: 'profile', params: { username: 'alice' } }">个人资料</router-link>
      <!-- 结果:/profile/alice -->
    • 参数v-slot:完全自定义链接内容和行为。

      html
      <router-link to="/dashboard" v-slot="{ href, isActive }">
        <a :href="href" :class="{ active: isActive }">控制台</a>
      </router-link>
    • 路由激活状态

      html
      <!-- 当前路由为 /user/profile -->
      <router-link to="/user">用户中心</router-link> 
      <!-- 激活类:router-link-active -->
      
      <router-link to="/user/profile">个人资料</router-link> 
      <!-- 激活类:router-link-active + router-link-exact-active -->
  • 常见用途:

    • 基本导航

      html
      <router-link to="/">首页</router-link>
      <router-link :to="{ name: 'user', params: { id: 1 } }">用户 1</router-link>
    • 带查询参数

      html
      <router-link :to="{ path: '/search', query: { q: 'vue' } }">搜索 Vue</router-link>
      <!-- 结果:/search?q=vue -->
    • 自定义激活样式

      html
      <router-link 
        to="/contact" 
        active-class="active-link"
        exact-active-class="exact-active-link"
      >
        联系我们
      </router-link>
    • 动态路径与参数

      html
      <!-- /posts/123 -->
      <router-link :to="`/posts/${postId}`">文章详情</router-link>
      
      <!-- /product/123?from=home -->
      <router-link :to="{
        name: 'product',
        params: { id: product.id },
        query: { from: 'home' }
      }">
        {{ product.name }}
      </router-link>
    • 导航守卫与事件:@

      html
      <router-link 
        to="/checkout" 
        @click.native.prevent="handleClick"
        :event="isLoggedIn ? 'click' : ''"
      >
        结算
      </router-link>
  • 注意事项:

    • 避免在to中混用path和name:优先使用 name 以解耦路径。
    • 动态参数需事先占位:使用 params 时,目标路由必须定义对应的参数占位符,如 /user/:id
    • 慎用replace:替换历史记录后用户无法通过浏览器后退按钮返回。
    • 性能优化:频繁变化的动态路由可结合 <keep-alive> 缓存组件状态。

<router-view>

<router-view>name?,v-slot?,,是 Vue Router 的核心组件,用于在SPA中渲染当前路由匹配的组件。它相当于一个动态占位符,根据路由规则切换显示内容。

  • name?string,支持多视图渲染,需在路由配置中定义 components 对象。

  • v-slot?{Component},暴露一个插槽,用来渲染路由组件。

  • 语法:

    • 渲染规则

      • 根据当前路由路径,自动匹配并渲染路由配置中对应的组件。
      • 支持嵌套路由,通过层级 router-view 实现父子组件嵌套渲染。
    • 命名视图:通过 name 属性支持多视图渲染,需在路由配置中定义 components 对象。

      • 1、布局组件中定义多个命名视图
      html
      <template>
        <div>
          <router-view name="header"></router-view>
          <router-view></router-view> <!-- 默认 name: default -->
          <router-view name="footer"></router-view>
        </div>
      </template>
      • 2、路由配置
      js
      const routes = [
        {
          path: '/',
          components: {
            default: Home,        // 默认视图渲染 Home 组件
            header: Header,       // 命名视图 header 渲染 Header 组件
            footer: Footer        // 命名视图 footer 渲染 Footer 组件
          }
        }
      ];
    • 嵌套路由:通过嵌套 router-view 实现多层组件结构。

      • 1、路由配置
      js
      const routes = [
        {
          path: '/user/:id',
          component: UserLayout,  // 父组件
          children: [
            {
              path: 'profile',
              component: UserProfile, // 子组件渲染在 UserLayout 的 <router-view> 中
            },
            {
              path: 'settings',
              component: UserSettings
            }
          ]
        }
      ];
      • 2、父组件模板
      html
      <!-- UserLayout.vue -->
      <template>
        <div>
          <h2>用户中心</h2>
          <router-view></router-view> <!-- 子路由组件在此渲染 -->
        </div>
      </template>
    • 路由插槽:暴露一个插槽,用来渲染路由组件。当想要获得其他功能时,插槽提供了额外的扩展性。

      html
      <router-view v-slot="{ Component }">
        <component :is="Component" />
      </router-view>
      
      <!-- 等价于 <router-view /> -->
    • 过渡动画:用 transition 包裹 router-view 实现路由切换动画。

      html
      <template>
        <router-view v-slot="{ Component }">
          <transition name="fade" mode="out-in">
            <component :is="Component" />
          </transition>
        </router-view>
      </template>
      
      <style>
      .fade-enter-active, .fade-leave-active {
        transition: opacity 0.3s;
      }
      .fade-enter-from, .fade-leave-to {
        opacity: 0;
      }
      </style>
    • 组件缓存:用 keep-alive 包裹 router-view 缓存组件状态。

      html
      <keep-alive>
        <router-view></router-view>
      </keep-alive>
    • 传递Props:通过路由配置向组件传递 Props

      js
      const routes = [
        {
          path: '/user/:id',
          component: UserProfile,
          props: true // 将路由 params 作为 props 传递(如 :id → props.id)
        },
        {
          path: '/about',
          component: About,
          props: { staticData: 'Hello' } // 传递静态对象
        },
        {
          path: '/dynamic',
          component: Dynamic,
          props: (route) => ({ query: route.query.q }) // 函数模式动态生成 props
        }
      ];
    • 路由元信息

      • 1、结合路由元信息 meta 控制视图逻辑。
      js
      const routes = [
        {
          path: '/admin',
          component: AdminDashboard,
          meta: { requiresAuth: true }
        }
      ];
      • 2、在组件中访问元信息。
      js
      export default {
        mounted() {
          if (this.$route.meta.requiresAuth) {
            // 检查权限逻辑
          }
        }
      }
  • 注意事项:

    • 唯一根元素:每个router-view对应路由配置中的一个组件,确保组件模板有唯一根元素,Vue3支持多根节点。
    • 命名视图匹配:若路由配置未提供对应名称的组件,命名视图区域将渲染为空。
    • 性能优化
      • 使用 keep-alive 缓存高频访问的页面。
      • 按需加载路由组件/异步组件提升首屏速度。

<>

<>

<>

<>

<>

<>

Router

useRouter()【

createRouter()@4

createRouter()({history,routes,scrollBehavior?,...}),是 VueRouter4 中用于创建路由实例的核心函数。替代了 VueRouter3 的 new VueRouter()。

  • historyRouterHistory,指定路由的历史模式。有以下三种内置模式:

  • routesRouteRecordRaw[],定义路由配置的数组。路由对象 RouteRecordRaw 包含以下常见属性:

    • pathstring,路由路径,支持动态参数,如 /user/:id
    • namestring,路由唯一名称,用于编程式导航。
    • componentComponent|()=>import(),对应组件或异步组件函数。
    • componentsobject,命名视图配置,用于多视图场景。
    • redirectstring|object,重定向目标。
    • childrenRouteRecordRaw[],嵌套路由配置。
    • metaany,路由元信息,用于权限控制等。
    • propsboolean|object|function,向组件传递 Props。
  • scrollBehavior?(to,from,savedPosition)=>PositionResult|Promise,控制页面滚动行为。

    • tostring|object,目标路由地址。

    • fromstring|object,来源路由地址。

    • savedPositionPosition|null,浏览器前进/后退时记录的滚动位置。

    • 返回:

    • positionPositionResult|Promise,可指定滚动位置({ top: number, left: number })、滚动到指定选择器({ selector: string })或保持原位(false)。

  • linkActiveClass?string默认:router-link-active,当目标路由是当前路由的子路径时激活 CSS 类名。

  • linkExactActiveClass?string默认:router-link-exact-active,仅当目标路由与当前路由完全匹配时激活 CSS 类名。

  • parseQuery(search)=>Record<string,any>,自定义查询参数 query 的解析函数。

  • stringifyQuery(query)=>string,自定义查询参数 query 的序列化函数。

  • fallbackboolean默认:true,在不支持 history.pushState 的浏览器中,是否回退到哈希模式

  • 返回:

  • routerRouter,返回一个路由实例,包含以下核心方法/属性:【TODO:添加链接】

  • 语法:

    • 控制页面滚动行为

      js
      scrollBehavior(to, from, savedPosition) {
        if (savedPosition) {
          return savedPosition; // 恢复历史滚动位置
        } else if (to.hash) {
          return { selector: to.hash }; // 滚动到锚点
        } else {
          return { top: 0 }; // 滚动到顶部
        }
      }
    • 使用qs库处理嵌套对象

      js
      import qs from 'qs';
      
      parseQuery: (search) => qs.parse(search, { ignoreQueryPrefix: true }),
      stringifyQuery: (query) => qs.stringify(query),
  • 注意事项:

    • 路由懒加载:使用 () => import() 语法实现组件按需加载。
    • TS支持:确保定义路由时使用 RouteRecordRaw 类型,以获得类型检查和自动补全。
    • 动态路由:通过 router.addRoute() 可在运行时动态添加路由。
  • 示例:完整配置

    js
    import { createRouter, createWebHistory } from 'vue-router';
    import Home from '../views/Home.vue';
    
    const router = createRouter({
      history: createWebHistory(import.meta.env.BASE_URL), // 基路径
      routes: [
        {
          path: '/',
          name: 'Home',
          component: Home,
          meta: { title: '首页' }
        },
        {
          path: '/about',
          name: 'About',
          component: () => import('../views/About.vue'),
          meta: { requiresAuth: true }
        }
      ],
      scrollBehavior(to, from, savedPosition) {
        return savedPosition || { top: 0 };
      },
      linkActiveClass: 'active-link',
      linkExactActiveClass: 'exact-active-link'
    });
    
    export default router;

createWebHashHistory()

createWebHashHistory()(base?),用于创建基于 哈希模式(Hash Mode) 的路由历史记录。

  • base?string默认:'',表示应用的基础路径,所有路由将相对于该路径解析。
  • 返回:
  • historyRouterHistory,返回一个RouterHistory对象,用于 Vue Router 的配置。
  • 语法:
    • base规范化
      • 自动添加前导斜杠,如 my-app/my-app
      • 尾部斜杠会被保留,如传入 /my-app/ 则保持为 /my-app/
    • base设置路由前缀:部署时可以通过base设置路由前缀,如/my-app/
  • 特性:
    • 哈希模式特点
      • URL 结构: 路由路径位于 # 之后,如 https://example.com/#/about
      • 无服务器配置要求: 哈希变化不会触发页面请求,服务器只需返回单个 HTML 文件。
      • 监听机制: 通过 hashchange 事件响应路由变化,兼容性良好。
  • 示例:设置路由前缀
    js
    import { createRouter, createWebHashHistory } from 'vue-router'
    
    const router = createRouter({
      history: createWebHashHistory('/my-app/'), // 路由前缀为 /my-app/
      routes: [
        // 定义路由...
      ]
    })
    // 部署后路径URL为:https://example.com/my-app/#/home

createWebHistory()

createWebHistory()(base?),用于创建基于 HTML5 History API 的路由历史记录,也称为“历史模式”。

  • base?string默认:'',表示应用的基础路径,所有路由将相对于该路径解析。

  • 返回:

  • historyRouterHistory,返回一个RouterHistory对象,用于 Vue Router 的配置。

  • 语法:

    • base规范化

      • 自动添加前导斜杠,如 my-app/my-app
      • 尾部斜杠会被保留,如传入 /my-app/ 则保持为 /my-app/
    • base设置路由前缀:部署时可以通过base设置路由前缀,如/my-app/

    • 服务器配置

      • Nginx
      sh
      location / {
        try_files $uri $uri/ /index.html;
      }
      • Apache
      sh
      RewriteEngine On
      RewriteBase /
      RewriteRule ^index\.html$ - [L]
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule . /index.html [L]
  • 特性:

    • 历史模式特点
      • URL结构:URL 路径无 #,如 https://example.com/about,更符合标准 URL 规范。
      • 依赖HTML5 History API:使用 pushState() 和 replaceState() 操作浏览历史记录,兼容现代浏览器。
      • 服务器配置要求:直接访问子路径如 https://example.com/about时,需确保服务器返回应用入口文件如 index.html,否则会触发 404 错误。
      • SPA友好:适合SPA,但需配合服务器配置。
  • 注意事项:

    • 部署路径匹配:若应用部署在子目录,如 /my-app/,需同时配置 base 参数和服务器路径规则。
    • 兼容性:不支持 IE9 及以下浏览器,需 Polyfill 或降级为哈希模式。
    • 开发环境:Vue CLI 或 Vite 的开发服务器已默认支持 History 模式,无需额外配置。
  • 示例:

    js
    import { createRouter, createWebHistory } from 'vue-router'
    
    const router = createRouter({
      history: createWebHistory('/my-app/'), // 基础路径为 /my-app/
      routes: [
        { path: '/', component: Home },
        { path: '/about', component: About }
      ]
    })
    // 部署后路径URL为:https://example.com/my-app/home

addRoute()【

removeRoute()【

hasRoute()【

getRoutes()【

beforeEach()【

afterEach()【

push()【

replace()【

Route

useRoute()【

SSR

createMemoryHistory()

createMemoryHistory()(),用于创建一个基于 内存 的路由历史记录,也称为“抽象模式”。

  • base?string默认:'',表示应用的基础路径,所有路由将相对于该路径解析。

  • 返回:

  • historyRouterHistory,返回一个RouterHistory对象,用于 Vue Router 的配置。

  • 语法:

    • base规范化

      • 自动添加前导斜杠,如 my-app/my-app
      • 尾部斜杠会被保留,如传入 /my-app/ 则保持为 /my-app/
    • base设置路由前缀:部署时可以通过base设置路由前缀,如/my-app/

    • 自定义初始状态:可通过选项对象初始化内存历史记录的初始路径和状态。

      js
      const history = createMemoryHistory({
        base: '/my-app/',
        initialEntries: ['/home'], // 初始路径
        initialState: { user: 'admin' } // 附加初始状态(可通过 router.currentRoute.value.state 访问)
      })
  • 特性:

    • 内存模式特点
      • 无URL依赖:路由状态完全存储在内存中,不修改浏览器 URL,适合无 DOM 的环境如 Node.js。
      • 手动导航控制:需通过编程式导航,如 router.push()router.replace()管理路由跳转。
      • SSR友好:服务端渲染时,每个请求需创建一个独立的内存历史实例,避免状态污染。
      • 轻量且隔离:不同实例之间的路由状态互不影响,适合多用户并发场景。
  • 常见用途:

    • 基本配置

      js
      import { createRouter, createMemoryHistory } from 'vue-router'
      
      const router = createRouter({
        history: createMemoryHistory('/my-app/'), // 基础路径为 /my-app/
        routes: [
          { path: '/', component: Home },
          { path: '/about', component: About }
        ]
      })
    • 在SSR中的应用

      js
      // 服务端代码(Node.js)
      export function createSSRRouter() {
        return createRouter({
          history: createMemoryHistory(),
          routes: [
            // 定义路由...
          ]
        })
      }
    • 测试环境中模拟路由

      js
      // 单元测试示例(Jest/Vitest)
      test('navigates to about page', async () => {
        const history = createMemoryHistory()
        const router = createRouter({ history, routes })
        await router.push('/about')
        expect(router.currentRoute.value.path).toBe('/about')
      })
  • 注意事项:

    • 不适用于浏览器环境:在浏览器中使用时,用户无法通过地址栏直接输入路径或使用前进/后退按钮导航。
    • 需手动同步状态:若需要将路由状态传递到客户端,如 SSR 脱水/注水,需显式处理序列化和反序列化。