Code前端首页关于Code前端联系我们

先搞懂,Vue2 Router 核心概念有哪些?

terry 7小时前 阅读数 13 #Vue

Vue2 时代,单页应用(SPA)开发里路由是绕不开的核心工具,Vue2 Router 作为官方路由解决方案,新手学的时候总感觉“看文档懂了,写代码就懵”,到底怎么学才能高效掌握?练手时又容易踩哪些坑?今天用问答形式把核心知识点和避坑技巧掰开揉碎讲清楚。

很多新手一上来就写代码,连“路由模式、路由表、导航守卫”这些基础概念都没理清,代码自然写得磕磕绊绊,简单说几个必懂概念:
  • 路由模式:Vue2 Router 有 hashhistory 两种模式。hash 靠 URL 里的 (xxx.com/#/home)实现路由切换,兼容性好;history 用 HTML5 History API,URL 更干净(xxx.com/home),但部署时要后端配合做重定向,否则刷新会404。
  • 路由配置(router.js):这是路由“地图”,用 routes 数组定义每个路径对应哪个组件,比如给 /about 路径配 About.vue 组件,还要考虑动态路由(带:id 这种参数)、嵌套路由(children 数组)。
  • 路由组件:指被路由直接控制渲染的组件,一般放在 views 文件夹(和 components 区分,后者是通用组件),路由匹配时会把组件渲染到 <router-view> 里。
  • 导航方式:分声明式(<router-link> 组件)和编程式(this.$router.push() 这类API),前者适合页面跳转,后者适合逻辑里跳转(比如登录成功后跳首页)。

新手学习路径:从“跟练”到“自主开发”怎么过渡?

不少人学路由停留在“复制文档代码”阶段,一到自己做项目就卡壳,分享个递进式学习法:

第一步:啃透官方文档+写基础 Demo

官方文档是最好的老师!先把“起步”“路由配置”“导航守卫”这些基础章节精读,边读边写 Demo:比如做个“首页-关于页-用户详情页”的小应用,用 hash 模式配好路由表,用 <router-link> 做跳转,再用 this.$router.push 做编程式导航,这一步重点是“理解路由和组件的对应关系”,以及两种导航方式的区别。

第二步:模仿成熟项目的路由设计

找个 Vue2 技术栈的开源后台管理系统(vue-element-admin 这类经典项目),看人家的 router.js 怎么组织:怎么用嵌套路由做侧边栏(/dashboard/analysis 这种层级)、怎么用动态路由加载组件(() => import('@/views/xxx') 实现懒加载)、怎么配置404页面(路径配 指向 NotFound.vue),模仿时思考“为什么这么设计”,比如懒加载是为了优化首屏加载速度。

第三步:主动 Debug 暴露问题

自己写项目时,故意搞点“错误”逼自己解决:比如把路由配置里的 component 写成 components(少个s),看控制台报错怎么说;或者嵌套路由时忘记在父组件里加 <router-view>,页面为什么不渲染;再比如导航守卫里 next() 忘写导致页面卡住… 解决这些问题的过程,比看十篇教程都管用。

路由配置里,新手最容易踩的3个坑

路由配置是“地基”,配置错了整个路由系统都跑不起来,这些高频坑得提前避:

坑1:动态路由参数“拿不到”或“匹配混乱”

想做个用户详情页,路径是 /user/:id,结果在组件里 this.$route.params.id 拿不到值?先检查路由配置里的路径是不是写对了(比如写成 /user/id 没加),再看跳转时有没有传参,如果多个路由路径“太像”,/user/user/:id 顺序放反,会导致 /user/123 匹配到 /user 而不是动态路由,要把动态路由放在更靠后的位置,让精确匹配先生效。

坑2:嵌套路由“页面不渲染”

做后台管理系统时,想让 /dashboard 下有 /dashboard/analysis/dashboard/monitor 两个子页面,结果子页面死活不显示,原因大概率是:父组件(Dashboard.vue)里没放 <router-view> 来承载子组件,或者路由配置里 children 数组的路径没写对(子路由路径不用加 ,比如写 analysis 而不是 /analysis,因为父路由已经是 /dashboard 了,子路由会自动拼接)。

坑3:404页面“配置了但不生效”

想做个404页面,路由里配了 { path: '*', component: NotFound },结果访问不存在的路径时没跳转?因为 Vue2 Router 的路由匹配是“先匹配先渲染”,如果404路由放在路由表最前面,前面的精确路由还没匹配就被404拦截了,必须把404路由放在路由表最后面,让前面的路由先匹配,匹配不到再走404。

导航守卫:逻辑控制的“双刃剑”,这些细节要注意

导航守卫用来控制路由跳转的权限(比如未登录不让进个人中心)、页面跳转前做埋点等,但新手用的时候很容易把“守卫顺序”和“next()”玩坏:

守卫执行顺序搞反

全局守卫(router.beforeEach)、路由独享守卫(beforeEnter)、组件内守卫(beforeRouteEnter 这些)的执行顺序是有规律的:导航触发后,先执行全局前置守卫 → 路由独享守卫 → 组件内的 beforeRouteEnter → 组件渲染 → 全局解析守卫(beforeResolve)→ 全局后置守卫(afterEach),如果搞不清顺序,做权限控制时容易出现“拦截了但页面还能进”的情况,比如想在全局守卫里判断登录状态,得确保逻辑在正确的阶段执行。

“next()”用错导致死循环或页面卡住

每个守卫里的 next 是控制导航是否继续的关键,比如在 beforeEach 里,如果你写了 if (未登录) { next('/login') },但忘记处理“已登录”的情况,就会导致无限循环(因为每次跳 /login 又会触发 beforeEach),正确做法是加 else { next() } 放行。beforeRouteEnter 里不能直接用 this(因为组件还没创建),要通过 next(vm => { ... }) 访问实例,这点也很容易忘。

路由传参:query、params、props 怎么选?

页面跳转时传数据是刚需,但用 query 还是 params,直接传还是用 props 解耦,新手经常混淆:

  • query 传参:参数会拼在 URL 上(xxx.com/user?name=张三),刷新页面参数还在,适合传非敏感、可暴露的信息,获取时用 this.$route.query.name
  • params 传参:参数不会显示在 URL 上(如果路由没配动态参数的话),刷新会丢失,适合传临时、敏感的信息,但如果是动态路由(/user/:id),params 里的 id 会对应 URL 里的 id,此时刷新不会丢,获取时用 this.$route.params.id
  • 用 props 解耦:路由组件里直接用 this.$route 会让组件和路由强耦合(比如换个页面复用组件就麻烦),可以在路由配置里开启 props: true,这样组件里可以用 props 接收参数,props: ['id'],然后直接用 id 而不是 this.$route.params.id,组件复用性更强。

路由模式:hash 和 history 该怎么选?

很多人纠结用哪种模式,其实看项目场景:

  • 如果是纯前端项目,不需要 SEO,也不想处理后端配置,选 hash 模式最省心,兼容性好到 IE9 都支持,部署时直接把打包后的文件丢服务器就行,刷新页面不会404(因为 后面的内容不会传给服务器)。
  • 如果追求 URL 美观,想做类似 xxx.com/about 这种路径,选 history 模式,但必须让后端配合:比如用 Nginx 部署时,要配置 try_files $uri $uri/ /index.html;,让所有请求都重定向到 index.html,否则用户刷新页面时,服务器找不到对应资源就会返回404。

实战思路:做个“简易博客系统”巩固路由知识

光看理论不够,得动手做项目,这里给个小项目思路,涵盖路由核心知识点:

需求拆解

做个有“首页、文章列表、文章详情、的博客,要求:

  • 首页展示欢迎语;
  • 文章列表页(/articles)显示所有文章标题,点击标题跳转到文章详情(/article/:id);
  • 关于页(/about)放站点信息;
  • 未匹配路径跳404。

路由配置(router.js)

import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home.vue'
import Articles from '@/views/Articles.vue'
import ArticleDetail from '@/views/ArticleDetail.vue'
import About from '@/views/About.vue'
import NotFound from '@/views/NotFound.vue'
Vue.use(Router)
export default new Router({
  mode: 'history', // 也可以试hash模式对比
  routes: [
    {
      path: '/',
      name: 'Home',
      component: Home
    },
    {
      path: '/articles',
      name: 'Articles',
      component: Articles,
      // 假设文章列表里有子路由?比如分类,这里演示嵌套路由
      children: [
        {
          path: 'category/:catId', // 子路由路径,完整路径是/articles/category/1
          component: () => import('@/views/ArticleCategory.vue') // 懒加载
        }
      ]
    },
    {
      path: '/article/:id',
      name: 'ArticleDetail',
      component: ArticleDetail,
      props: true, // 开启props传参,组件里用props接收id
    },
    {
      path: '/about',
      name: 'About',
      component: About
    },
    {
      path: '*',
      component: NotFound
    }
  ]
})

组件里的导航实践

  • 声明式导航:在 Home.vue 里用 <router-link to="/articles">进入文章列表</router-link> 跳转到文章列表。
  • 编程式导航:在 Articles.vue 里,点击文章标题时用 this.$router.push({ name: 'ArticleDetail', params: { id: article.id } }) 跳详情页(也可以用 query 传参对比效果)。
  • 嵌套路由渲染:在 Articles.vue 里加 <router-view></router-view>,这样访问 /articles/category/1 时,ArticleCategory.vue 会渲染到这里。

导航守卫加权限(模拟)

比如文章详情页需要登录才能看,在路由独享守卫里加逻辑:

{
  path: '/article/:id',
  name: 'ArticleDetail',
  component: ArticleDetail,
  props: true,
  beforeEnter: (to, from, next) => {
    const isLogin = localStorage.getItem('token') // 模拟登录状态
    if (isLogin) {
      next()
    } else {
      next('/login') // 跳登录页
    }
  }
}

学 Vue2 Router 没有捷径,核心是“理解概念→模仿实践→主动踩坑→总结规律”,把路由配置、导航方式、传参逻辑这些基础打牢,再结合项目场景选择模式、处理守卫,自然能从“写得出来”到“写得好”,如果练手时遇到问题,先看控制台报错(Vue 控制台对路由问题的提示很友好),再回到文档对应章节找答案,慢慢就会形成肌肉记忆啦~

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门