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

不少刚接触Vue Router的同学,总会对hash和params犯迷糊—这俩在路由里到底扮演啥角色?传参咋用?区别在哪?今天用问答形式,把这些问题拆明白,帮你彻底理清逻辑~

terry 3小时前 阅读数 3 #Vue

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路径,123params.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前端网发表,如需转载,请注明页面地址。

发表评论:

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

热门