先搞懂,Vue2 Router 核心概念有哪些?
Vue2 时代,单页应用(SPA)开发里路由是绕不开的核心工具,Vue2 Router 作为官方路由解决方案,新手学的时候总感觉“看文档懂了,写代码就懵”,到底怎么学才能高效掌握?练手时又容易踩哪些坑?今天用问答形式把核心知识点和避坑技巧掰开揉碎讲清楚。
很多新手一上来就写代码,连“路由模式、路由表、导航守卫”这些基础概念都没理清,代码自然写得磕磕绊绊,简单说几个必懂概念:- 路由模式:Vue2 Router 有
hash
和history
两种模式。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前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。