vue-router知识点

223 阅读15分钟
  1. 单页应用和多页应用的区别是什么?
  2. Vue Router中如何监听路由变化,有几种方式?
  3. Vue Router中有哪些路由模式,它们有什么区别?
  4. Vue Router中页面跳转时,如何传递参数?
  5. Vue Router中实现页面跳转时,如何保存页面的状态?

1、 vue-router怎么重定向页面?

2、 vue-router怎么配置404页面?

3、 切换路由时,需要保存草稿的功能,怎么实现呢?

4、 vue-router路由有几种模式?说说它们的区别?

5、 vue-router有哪几种导航钩子( 导航守卫 )?

6、 说说你对router-link的了解

7、 vue-router如何响应路由参数的变化?

8、 你有看过vue-router的源码吗?说说看

9、 切换到新路由时,页面要滚动到顶部或保持原先的滚动位置怎么做呢?

10、 在什么场景下会用到嵌套路由?

11、 如何获取路由传过来的参数?

12、 说说active-class是哪个组件的属性?

13、 在vue组件中怎么获取到当前的路由信息?

14、 vur-router怎么重定向?

15、 怎样动态加载路由?

16、 怎么实现路由懒加载呢?

17、 如果让你从零开始写一个vue路由,说说你的思路

18、 说说vue-router完整的导航解析流程是什么?

19、 路由之间是怎么跳转的?有哪些方式?

20、 如果vue-router使用history模式,部署时要注意什么?

21、 route和router有什么区别?

22、 vue-router钩子函数有哪些?都有哪些参数?

23、 vue-router是用来做什么的?它有哪些组件?

1.单页应用和多页应用的区别是什么?

单页应用(SPA)和多页应用(MPA)的核心区别如下:

1. 页面加载方式

  • SPA:仅首次加载完整HTML/CSS/JS,后续内容通过JavaScript动态替换(如React/Vue路由切换),无页面刷新
  • MPA:每次跳转都向服务器请求新HTML页面,整页刷新

2. 用户体验

  • SPA:交互流畅(类似桌面应用),切换内容无白屏。
  • MPA:每次跳转有短暂白屏,依赖网络速度。

3. 技术实现

  • SPA
    • 前端框架(React/Angular/Vue)管理视图和状态。
    • 后端仅提供API接口(前后端分离)。
  • MPA
    • 后端渲染HTML(如PHP/JSP模板)。
    • 前后端耦合度高(常混合业务逻辑)。

4. 性能特点

  • SPA
    • 首屏较慢(需加载所有资源)。
    • 后续操作快(仅请求数据)。
  • MPA
    • 首屏较快(按需加载单个页面)。
    • 重复加载资源(如公共CSS/JS)。

5. SEO优化

  • SPA:传统SEO较弱(依赖JS渲染),需服务端渲染(SSR)或预渲染优化。
  • MPA:天然SEO友好(静态HTML直接可抓取)。

适用场景

  • SPA:后台管理系统、社交平台(如Gmail、Twitter)。
  • MPA:内容型网站、电商平台(如新闻站、传统企业官网)。

一句话总结
SPA用动态加载换流畅体验,MPA以整页刷新保简单直接。

2.Vue Router中如何监听路由变化,有几种方式?

3.Vue Router中有哪些路由模式,它们有什么区别?

(4)Vue Router中页面跳转时,如何传递参数?

image.png (5)Vue Router中实现页面跳转时,如何保存页面的状态?

1、 vue-router怎么重定向页面?

redirect alias

方法一:在routes:[{
{ path: '/a', redirect: '/b' }
}]
方法二:别名
routes: [
{ path: '/a', component: A, alias: '/b' }
]

2、 vue-router怎么配置404页面?

将path:'*' , *放在最后,因为如果你放在前面会导致后面的的不能匹配

3、 切换路由时,需要保存草稿的功能,怎么实现呢?

用keep-alive缓存那个路由 或者本地缓存

在beforeDestroy中加入check功能, 当检测到有草稿时, 自动保存到vuex或者storage中或者window中等等 但是我要说的是, 这种方法是不靠谱的, 如果我是刷新页面呢! 建议采用, 实施保存操作, 保存在storage中较为靠谱, 当然这种操作牺牲是比较多的,可以用beforeDestroy结合window.onbeforeunload解决性能问题

4、 vue-router路由有几种模式?说说它们的区别?

结合vue3性能调优+deepseek

vue-router 支持三种路由模式:

  1. Hash 模式

    • URL 格式:http://example.com/#/path
    • 通过 URL 中的 # 后的哈希值实现路由,不触发页面刷新
    • 兼容性最好,支持所有浏览器,无需服务器配置。
  2. History 模式

    • URL 格式:http://example.com/path(无 #,更美观)
    • 基于 HTML5 history.pushState API,需服务器配置支持(所有路径重定向到 index.html),否则直接访问子路由会返回 404。
  3. Abstract 模式

    • 用于非浏览器环境(如 React Native、Electron),路由信息保存在内存中,不依赖 URL。

核心区别

  • Hash 模式兼容性强但 URL 带 #,History 模式 URL 更规范但需服务器配合,Abstract 模式用于非 Web 环境。

5、 vue-router有哪几种导航钩子( 导航守卫 )?

共有三种守卫:

1:全局前置守卫,全局解析守卫,全局后置钩子:beforeEach, beforeResolve,afterEach,

2:路由配置守卫:beforeEnter

3:组件独享守卫:beforeRouteEnter,beforeRouteUpdate,beforeRouteLeave

他们执行顺序:全局》路由》组件 除了afterEach全局后置外,其他的守卫中务必要调用next(),否则无法完成导航 还有注意全局前置守卫可以用来进行拦截,(登录拦截)

6、 说说你对router-link的了解

vue-router插件的其中一个组件, 用于跳转路由, 类似于a标签, 它一般也会渲染成a标签, 但是可以通过tag来变更默认渲染元素, 通过to来跳转。需 exact 精确匹配

7、 vue-router如何响应路由参数的变化?

image.png

8、 你有看过vue-router的源码吗?说说看

9、 切换到新路由时,页面要滚动到顶部或保持原先的滚动位置怎么做呢?

通过router 的meta来记录需要保存滚动条的位置,在new VueRouter()时调用scrollBehavior(to, from, savedPosition) {return { x: 0, y: 0 }}的方法

10、 在什么场景下会用到嵌套路由?

举个例子,例如做个管理系统,顶部栏和左侧菜单栏是全局通用的,那就应该放在父路由,而右下的页面内容部分放在子路由

11、 如何获取路由传过来的参数?

如果使用query方式传入的参数使用this.$route.query 接收
如果使用params方式传入的参数使用this.$router.params接收

image.png

image.png props也可以是一个函数,这个函数提供一个route参数,这样就可以将参数转换为另一种类型,将静态值与基于路由的值结合,

12、 说说active-class是哪个组件的属性?

active-class是vue-router模块的router-link组件中的属性,用来做选中样式的切换

13、 在vue组件中怎么获取到当前的路由信息?

在 Vue 组件中,可以通过 this.$route 获取当前的路由信息。this.$route 是一个包含当前路由状态的对象,提供了以下常用属性:

  • path: 当前路由的路径(如 /user/123)。
  • params: 动态路由参数(如 { id: '123' })。
  • query: 查询参数(如 { name: 'John' })。
  • hash: 当前路由的 hash 值(如 #section)。
  • fullPath: 完整的 URL 路径(如 /user/123?name=John#section)。
  • name: 路由名称(如果定义了)。
  • matched: 当前路由匹配的所有路由记录数组。

示例

<template>
  <div>
    <p>当前路径: {{ $route.path }}</p>
    <p>路由参数: {{ $route.params }}</p>
    <p>查询参数: {{ $route.query }}</p>
    <p>Hash: {{ $route.hash }}</p>
    <p>完整路径: {{ $route.fullPath }}</p>
    <p>路由名称: {{ $route.name }}</p>
  </div>
</template>

<script>
export default {
  mounted() {
    console.log('当前路由信息:', this.$route);
  }
}
</script>

监听路由变化

如果需要监听路由变化,可以使用 watch

export default {
  watch: {
    '$route'(to, from) {
      console.log('路由从', from.path, '变化到', to.path);
    }
  }
}

使用 useRoute(Vue 3 + Composition API)

在 Vue 3 中,可以使用 useRoute 钩子:

import { useRoute } from 'vue-router';

export default {
  setup() {
    const route = useRoute();
    console.log('当前路径:', route.path);
  }
}

通过这些方法,你可以轻松获取和监听当前路由信息。

15、 怎样动态加载路由?

在 Vue 中动态加载路由(Dynamic Route Addition)通常用于按需加载路由配置(如根据用户权限或应用状态),以下是详细的实现方法:


1. 核心方法:router.addRoute()

Vue Router 提供了 router.addRoute() 方法,允许在运行时动态添加路由。
适用场景

  • 根据用户权限动态注册路由
  • 应用模块按需加载
  • 延迟加载特定功能的路由

2. 基础实现步骤

(1) 定义静态路由(初始路由)
// router.js
import { createRouter, createWebHistory } from 'vue-router';

const staticRoutes = [
  {
    path: '/login',
    component: () => import('./views/Login.vue')
  }
];

const router = createRouter({
  history: createWebHistory(),
  routes: staticRoutes,
});

export default router;
(2) 动态加载路由

在需要时(如用户登录后、按钮点击时)动态添加路由:

// 在组件或逻辑层中
import router from './router';

// 示例:动态加载用户仪表盘路由
const loadDashboardRoute = async () => {
  // 动态导入组件(懒加载)
  const DashboardComponent = () => import('./views/Dashboard.vue');
  
  // 添加新路由
  router.addRoute({
    path: '/dashboard',
    name: 'Dashboard',
    component: DashboardComponent,
    meta: { requiresAuth: true }
  });

  // 可选:导航到新路由
  router.push('/dashboard');
};

3. 动态加载嵌套路由

如果要为现有路由添加嵌套子路由,需指定父路由的 name

// 假设已存在一个 name 为 'Admin' 的父路由
router.addRoute('Admin', { // 指定父路由名称
  path: 'settings',
  component: () => import('./views/AdminSettings.vue')
});

4. 结合权限控制的完整示例

(1) 定义动态路由表
// dynamicRoutes.js
export const asyncRoutes = [
  {
    path: '/admin',
    name: 'Admin',
    component: () => import('./views/Admin.vue'),
    meta: { role: 'admin' },
    children: [
      {
        path: 'users',
        component: () => import('./views/AdminUsers.vue')
      }
    ]
  },
  {
    path: '/user',
    name: 'User',
    component: () => import('./views/User.vue'),
    meta: { role: 'user' }
  }
];
(2) 根据权限动态加载
// 在权限验证逻辑中
import { asyncRoutes } from './dynamicRoutes';

// 假设用户角色为 'admin'
const userRole = 'admin';

// 过滤有权限的路由
const allowedRoutes = asyncRoutes.filter(route => 
  route.meta.role === userRole
);

// 动态添加路由
allowedRoutes.forEach(route => {
  router.addRoute(route);
});

// 检查当前路径是否匹配新路由(避免停留在不存在的路径)
if (!router.currentRoute.value.matched.length) {
  router.replace('/');
}

5. 动态移除路由

使用 router.removeRoute(routeName) 按名称移除路由:

// 移除 name 为 'Admin' 的路由及其子路由
router.removeRoute('Admin');

6. 验证动态路由是否生效

(1) 查看已注册路由
console.log(router.getRoutes());
(2) 检查路由是否存在
const routeExists = router.hasRoute('Dashboard'); // 根据路由名称检查

7. 注意事项

  1. 导航守卫处理
    动态添加路由后,若当前路径与新路由匹配,需手动触发 router.push() 或重定向。
  2. 避免重复添加
    使用 router.hasRoute() 检查路由是否已存在。
  3. 组件加载失败处理
    对动态导入 (import()) 添加错误回调:
    () => import('./views/Admin.vue')
      .catch(() => {
        console.error('组件加载失败');
        // 返回一个错误组件或重定向
      })
    
  4. 服务端渲染 (SSR)
    动态路由需与服务端渲染逻辑兼容(如 Nuxt.js 的特定处理)。

8. 完整流程图

触发动态加载条件(如用户登录)
      ↓
加载动态路由配置(从 API 或本地)
      ↓
过滤有权限的路由
      ↓
遍历添加路由(router.addRoute())
      ↓
验证当前路径是否有效
      ↓
更新导航或跳转

通过动态加载路由,可以实现灵活的权限管理和代码分割优化!

16、 怎么实现路由懒加载呢?

在 Vue 中实现路由懒加载(也叫按需加载)可以显著减少应用的初始包体积,提升首屏加载速度。以下是具体的实现方法:


1. 基本实现(基于动态 import 语法)

使用 动态 import() 语法(ES6 标准)结合 Webpack 的代码分割功能,将路由组件按需加载:

// router.js
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  {
    path: '/home',
    name: 'Home',
    component: () => import('./views/Home.vue'), // 动态导入组件
  },
  {
    path: '/about',
    name: 'About',
    component: () => import('./views/About.vue'),
  },
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;
  • 原理:Webpack 会将 import() 语法标记为代码分割点,自动将组件打包成独立的 chunk 文件,当访问对应路由时才会加载。
  • 生成的文件:构建后会在 dist/js 目录下生成类似 chunk-abc123.js 的文件。

2. 自定义 Chunk 名称(Webpack 魔法注释)

通过 Webpack 的魔法注释(Magic Comments)指定生成的 chunk 名称,便于调试和预加载:

component: () => import(/* webpackChunkName: "home" */ './views/Home.vue')
  • 效果:生成的 chunk 文件会被命名为 home.[hash].js
  • 注意:需确保 Webpack 配置中允许使用魔法注释(默认支持)。

3. 兼容 Babel 配置

如果项目使用 Babel,需确保安装了 @babel/plugin-syntax-dynamic-import 插件以支持动态 import 语法:

npm install --save-dev @babel/plugin-syntax-dynamic-import

babel.config.js 中添加插件:

module.exports = {
  plugins: ['@babel/plugin-syntax-dynamic-import'],
};

4. Vue 3 的 defineAsyncComponent(可选)

如果需要更精细控制异步加载行为(如加载状态、错误处理),可以使用 defineAsyncComponent

import { defineAsyncComponent } from 'vue';

const AsyncComponent = defineAsyncComponent(() =>
  import('./components/AsyncComponent.vue')
);

// 在路由中使用
const routes = [
  {
    path: '/async',
    component: AsyncComponent,
  },
];

5. 旧版 Vue/Webpack 的 require.ensure(不推荐)

在 Webpack 2 及以下版本中,可以使用 require.ensure(已逐渐被动态 import 替代):

component: (resolve) => {
  require.ensure([], () => {
    resolve(require('./views/Home.vue'));
  }, 'home'); // 'home' 是 chunk 名称
}

验证懒加载是否生效

  1. 构建产物检查:运行 npm run build 后,检查 dist/js 目录是否有多个 chunk 文件。
  2. 浏览器 Network 面板:访问不同路由时,观察是否有新的 JS 文件被加载。

注意事项

  1. 预加载:结合 <link rel="prefetch"> 提前加载低优先级路由(Webpack 4+ 默认对异步 chunk 启用 prefetch)。
  2. 避免过度拆分:过多的小 chunk 文件可能影响缓存效率和 HTTP/2 性能,需合理平衡。

通过路由懒加载,可以显著优化大型应用的性能!

17、 如果让你从零开始写一个vue路由,说说你的思路

为了方便后期维护,建议独立出一个 router.js 文件
npm install vue-router
引入注册
import Router from 'vue-router';
Vue.user(Router);
向外暴露出一个router实例
export default new Router({
    mode: '',
    path: '',
    name: '',
    ...
});

18、 说说vue-router完整的导航解析流程是什么?

1.导航被触发;2.在失活的组件里调用beforeRouteLeave守卫;3.调用全局beforeEach守卫;4.在复用组件里调用beforeRouteUpdate守卫;5.调用路由配置里的beforeEnter守卫;6.解析异步路由组件;7.在被激活的组件里调用beforeRouteEnter守卫;8.调用全局beforeResolve守卫;9.导航被确认;10..调用全局的afterEach钩子;11.DOM更新;12.用创建好的实例调用beforeRouteEnter守卫中传给next的回调函数。

Vue Router 的导航解析流程是一个完整且有序的链式过程,包含多个导航守卫的执行和数据流转。以下是完整的导航解析流程(按执行顺序排列):


1. 导航触发

通过以下方式触发导航:

  • 点击 <router-link>
  • 调用 router.push()/router.replace()/router.go()

2. 调用离开守卫(组件级)

  • beforeRouteLeave
    当前组件(即将离开的组件)的离开守卫。
    典型用途:表单未保存提示、清理定时器。
    // 在组件内定义
    beforeRouteLeave(to, from, next) {
      if (this.isFormDirty) {
        const confirmLeave = confirm('数据未保存,确认离开?');
        next(confirmLeave); // next(false) 取消导航
      } else {
        next(); // 继续导航
      }
    }
    

3. 全局前置守卫

  • router.beforeEach()
    全局路由前置守卫,在每次导航前调用。
    典型用途:权限验证、登录检查。
    router.beforeEach((to, from, next) => {
      if (to.meta.requiresAuth && !isLoggedIn()) {
        next('/login'); // 重定向到登录页
      } else {
        next(); // 继续导航
      }
    });
    

4. 调用组件复用守卫(组件级)

  • beforeRouteUpdate
    当路由变化但组件被复用时触发(如动态参数 /user/:id 变化)。
    典型用途:更新动态参数对应的数据。
    beforeRouteUpdate(to, from, next) {
      this.userId = to.params.id;
      this.loadUserData();
      next();
    }
    

5. 路由独享守卫

  • beforeEnter
    在路由配置中定义的路由独享守卫。
    典型用途:特定路由的访问控制。
    const routes = [
      {
        path: '/admin',
        component: Admin,
        beforeEnter: (to, from, next) => {
          if (!isAdmin()) next('/403'); // 权限不足跳转
          else next();
        }
      }
    ];
    

6. 解析异步组件

加载目标路由对应的异步组件(如懒加载的组件)。

component: () => import('./Admin.vue') // 动态导入组件

7. 调用进入守卫(组件级)

  • beforeRouteEnter
    目标组件(即将进入的组件)的进入守卫。
    关键特性:此时组件实例尚未创建,无法访问 this
    典型用途:预取数据。
    beforeRouteEnter(to, from, next) {
      // 通过回调访问组件实例
      next(vm => {
        vm.fetchData(to.params.id); // vm 是组件实例
      });
    }
    

8. 全局解析守卫

  • router.beforeResolve()
    全局守卫,在所有组件守卫和异步组件解析完成后调用。
    典型用途:最终确认导航(如数据预加载)。
    router.beforeResolve((to, from, next) => {
      if (to.meta.requiresData) preloadData().then(next);
      else next();
    });
    

9. 确认导航

所有守卫通过后,导航被确认,触发以下操作:

  1. 更新 URL(History API 操作)
  2. 销毁旧组件(若不再复用)
  3. 创建新组件实例

10. 全局后置钩子

  • router.afterEach()
    导航完成后触发,无法修改导航
    典型用途:埋点统计、页面滚动复位。
    router.afterEach((to, from) => {
      logPageView(to.path); // 记录页面访问
      window.scrollTo(0, 0); // 滚动到顶部
    });
    

11. 更新 DOM

渲染目标组件,完成视图更新。


12. 执行 beforeRouteEnternext 回调

此时组件已创建,可通过回调访问组件实例:

beforeRouteEnter(to, from, next) {
  next(vm => {
    vm.initData(); // 安全操作组件实例
  });
}

导航中断场景

在上述任何守卫中调用以下方法会中断导航:

  • next(false):取消导航,恢复原 URL
  • next('/login'):重定向到新路径
  • throw Error:导航终止并触发错误

流程图解

触发导航 → 调用离开守卫 → 全局前置守卫 → 组件复用守卫 → 路由独享守卫 → 
解析异步组件 → 进入守卫 → 全局解析守卫 → 确认导航 → 
更新 DOM → 全局后置钩子 → 执行进入守卫回调

通过理解这一流程,可以精准控制路由行为(如权限、数据预加载),确保应用逻辑的可靠性!

19、 路由之间是怎么跳转的?有哪些方式?

this.$router.push/replace/go/resolve router-link to

20、 如果vue-router使用history模式,部署时要注意什么?

服务器的404页面需要重定向到index.html

21、 route和router有什么区别?

route代表当前路由对象,router代表整个vue实例下的路由对象,即router是new vueRouter的实例

22、 vue-router钩子函数有哪些?都有哪些参数?

全局的:beforeEach、beforeResolve、afterEach 路由的:beforeEnter 组件的:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave 参数:to、from、next;正对不同的钩子函数参数有所差异。

23、 vue-router是用来做什么的?它有哪些组件?

vue-router路由,通俗来讲主要是来实现页面的跳转,通过设置不同的path,向服务器发送的不同的请求,获取不同的资源。 主要组件:router-view、router-link