不少刚接触Vue Router的同学,总会对hash和params犯迷糊—这俩在路由里到底扮演啥角色?传参咋用?区别在哪?今天用问答形式,把这些问题拆明白,帮你彻底理清逻辑~
Vue Router里的hash是干啥的?和路由模式有啥关系?
问:经常看到URL里带#,比如http://xxx.com/#/home
,这就是hash吧?它和Vue Router的路由模式有啥关系?
答:对的,这个后面的内容就是hash~Vue Router有两种常用路由模式:hash模式和history模式,hash模式下,URL必须带,浏览器会把后面的内容当作“锚点”处理,关键是,当后面的内容变化时,浏览器不会向服务器发请求(这很重要!),前端就能通过window.onhashchange
事件监听变化,从而实现单页应用的路由切换,简单说,hash模式是利用浏览器特性,让前端能自己控制路由跳转,还不刷新页面~
那hash和路由路径的关系是?比如#/user/123
里的/user/123
是啥?这其实是hash模式下的“虚拟路径”,如果路由配置了动态路由(比如path: '/user/:id'
),那这里的123
就是params.id
,所以hash路径里是可以包含params参数的~
params又是什么?为啥要用它传参?
问:params听起来像“参数”,它在Vue Router里是咋用的?和普通传参有啥区别?
答:params是Vue Router里的动态路由参数,专门用来在路由路径里传递可变数据,举个实际例子:做用户详情页时,每个用户的ID不一样,总不能给每个用户都写一个路由吧?这时候就用动态路由+params——路由配置写成{ path: '/user/:userId', component: UserDetail }
,这里的:userId
就是params的“占位符”。
当你在代码里用router.push({ name: 'UserDetail', params: { userId: 123 } })
跳转时,URL会变成/user/123
(history模式)或者/#/user/123
(hash模式),然后在UserDetail
组件里,通过this.$route.params.userId
就能拿到123
,这种方式的好处是参数嵌入URL,用户刷新页面、收藏链接都不会丢数据,而且URL语义化(一看就知道是用户123的详情页)~
hash和params的核心区别在哪?别再搞混啦!
问:有时候看URL里的hash路径包含了params,感觉俩东西缠在一起,咋区分它们的核心区别?
答:得从定义、传参逻辑、URL表现这几个角度拆明白:
定义本质不同
hash是路由模式的实现方式+前端路由切换的载体(比如hash模式下URL必须带,靠hashchange
事件实现无刷新跳转);
params是动态路由传参的机制,专门用来在路由路径里传递可变数据,属于路由系统的“传参工具”。
传参逻辑不同
hash“传参”比较灵活:可以在hash路径里放params(动态路由场景),也能在hash后面挂query参数(比如#/list?page=1
);
但params传参必须依赖路由配置里的动态段(比如:userId
),参数值会直接替换到URL路径里,和query那种?xxx=yyy
的形式完全不同。
举个直观例子:路由配置是{ name: 'User', path: '/user/:id', component: User }
- 用hash模式时,URL是
http://xxx.com/#/user/123
→ 这里#/user/123
是hash路径,123
是params.id
; - 换成history模式,URL变成
http://xxx.com/user/123
→ 没了,但params.id
还是123
。
这就能看出:hash是路由模式的“外在表现”,params是动态传参的“内在机制”,在hash模式下它们会“结合”出现在URL里,但功能本质不一样~
实际开发中,hash和params咋配合更顺手?
问:做项目时,啥场景用hash+params?啥场景换其他方式?
答:得看需求和技术限制:
场景1:兼容老浏览器,选hash模式+params
如果项目要兼容IE9及以下(这些浏览器不支持history模式依赖的HTML5 History API),就用hash模式,用params做动态路由传参(比如用户ID、商品ID),既满足无刷新跳转,又能让参数嵌在URL里,刷新不丢数据,像企业内部老系统、政府项目这类对兼容性要求高的,常用这种组合~
场景2:追求URL优雅,用history模式+params
后台管理系统、ToC的web应用,一般更在意URL美观(没有更专业),这时候选history模式,配合params做动态路由,URL变成/admin/user/123
这种语义化路径,用户体验和SEO(虽然单页应用SEO弱,但路径友好度有帮助)都更好~
场景3:临时传参,别用params!
如果只是组件间临时传点数据,不想让参数出现在URL里,别用params(因为params要么嵌URL,要么刷新就丢),这时候可以用Vuex、Pinia存,或者用router.push
的query参数(但query是明文在URL的后面,比如/list?page=1
)~
params传参没效果?踩过这些坑吗?
问:写代码时,params传了但拿不到,咋排查?
答:这几个常见坑要注意:
路由配置没加动态段
比如路由只写了path: '/user'
,但代码里用router.push({ name: 'User', params: { id: 123 } })
→ 这样params根本传不进去!因为路由路径里没给params留“位置”(:id
这种占位符),解决方法:把路由改成path: '/user/:id'
~
用path跳转,没写name
如果写成router.push({ path: '/user', params: { id: 123 } })
→ 无效!官方文档明确说:如果用path跳转,params会被忽略(因为path是固定路径,没法把params拼进去),必须用name跳转,比如{ name: 'User', params: { id: 123 } }
~
刷新后params丢了
如果路由没配动态段,却用params传参,刷新页面后params就没了(因为URL里没存这些参数),这时候要么给路由加动态段,要么换query传参~
hash模式和history模式下,hash和params表现有啥不同?
问:切换路由模式后,hash和params在URL里的表现咋变了?
答:这得看路由模式的特性:
- hash模式:URL必须带,hash路径是
#/xxx
,如果用了params(动态路由),params会出现在后的路径里,比如#/user/123
; - history模式:URL不带,params作为动态路由参数,直接出现在普通路径里,比如
/user/123
,这时候“hash”在路由模式层面不存在(除非你手动在URL里加,但路由系统不会这么用)。
简单总结:hash模式里,hash是URL的“标识”,params是hash路径里的动态部分;history模式里,没有hash(路由模式层面),params是普通URL路径里的动态部分~
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。