vue路由hash模式引发的血案
背景
路径1:
https://xxxxx.djtest.cn/driver-register/index.html?hmsr=qqqqq#/register
路径2:
https://xxxxx.djtest.cn/driver-register/index.html#/register?hmsr=qqqqq
大家平常用那个什么格式的链接,路径1还是路径2????
我一直习惯用路径2,可是就在前不久出现了一个线上bug????????????。这个bug原因还是路径不规范造成的,当是我一脸懵逼,我是谁,我在哪????
url的组成
协议部分、域名部分、端口部分、虚拟目录部分、文件名部分、参数部分、锚部分
注:端口不是一个URl必须的部分,如果省略端口部分,将采用默认端口。
相信大家对于url每一部分都很了解。在这就简单提一下,就不浪费大家的时间了。
使用中遇到的问题
问题1:
【路径1】和【路径2】都能正常打开页面,它们的区别是什么,谁才是规范的url?
【路径1】锚部分
【路径2】锚部分
通过控制台的输出,我们发现两个路径打印出来的参数部分和锚部分是不一样,为啥??
url的锚部分是从“#”开始到最后,都是锚部分。锚部分不是url的必需部分。url的参数部分是从“?”开始到“#”为止之间的部分。参数部分也不是url的必需部分。根据url参数部分和锚部分的定义以及控制台输出的结果,我们可以得出【路径1】是符合规范url。
问题2:
由问题1得出【路径1】是符合url规范的路径。但是在开发中我发现问题又来了,用this.$route.query 无法获取参数?在页面中增加代码(如下)
created() {
console.log('*******************')
console.log('this.$route.query.hmsr:'+this.$route.query.hmsr)
console.log('window.location.search:'+window.location.search)
console.log('*******************')
}
查看打印结果
【路径1】:
【路径2】:
why???
我查阅vue router相关文档,对此并没有说明,自己猜想应该是vue router内部做了相应的处理。
问题就来了,我们应该在项目中如何获取参数呢?
写一个获取参数的通用方法:
function getUrlParam(key) {
var url = window.location.href;
var startIndex = url.indexOf('?');
var params = {};
if (startIndex > -1) {
var str = url.substring(startIndex + 1);
var arr = str.split('&');
for (var i = 0; i < arr.length; i++) {
var kv = arr[i].split('=');
if (kv[1].indexOf('#') > -1) {
kv[1] = kv[1].substring(0, kv[1].indexOf('#'));
}
params[kv[0]] = kv[1];
}
}
return params[key];
}
【路径1】
【路径2】
注意:在传统模式开发中,如果在url中search与hash同时存在,你的hash值一定要放在search后面。
问题3:
通过上面获取参数方法,【路径1】和【路径2】都能获取到了对应的参数,这回没有问题了吧,但是想象很美好,现实很残酷。
现实是这样的,h5页面放到app中时,会在配置的路径上添加一些参数。app开发人员添加规则是在锚部分的前面添加参数。但是如果我们的页面使用vue-router进行页面跳转同时增加参数,url上就会出现双“ ?”的情况,那参数还能获取吗?
怎么办后面一个问号的参数获取不到?
方案一:优化获取参数函数,使其能获取多问号的参数
function getUrlAllParam(...args) {
if (args.length === 0) return undefined
const url = decodeURIComponent(window.location.href)
const reg = args.length === 1
? new RegExp(`[&?]${args[0]}=([^&%#]+)`)
: new RegExp(`[&?](?:${args.join('|')})=([^&%#]+)`)
const matchArray = url.match(reg)
return matchArray === null ? undefined : matchArray[1]
}
调用:
this.getUrlAllParam('hmsr') //获取参数的key
方案二: 不使用vue router跳转。跳转之前把要跳转的路径拼接好,再跳转,让路径中不存双问好的问题。
fomartUrl(url,params,hash){
// url 是访问路径 字符串(不包含参数部分和锚部分的)
// params 参数是数组[{name:'hmsr',value:'1222'}]
if(!url){
return false;
}
let query = '';
if(params && params.length>0){
let queryAttr =[];
for(let i =0;params.length>i;i++){
queryAttr.push(params[i].name + '=' +params[i].value)
}
query = queryAttr.join('&')
}
if(hash){
return url + '?' + query + '#/' + hash
} else {
return url + '?' + query
}
}
调用:
const goHref = this.fomartUrl(
'http://localhost:8080/',
[{name:'hmsr',value:'2222'},{name:'aaa',value:'11'}],
'outsideIndex')
window.location.href = goHref
总结
这是在开发过程中,遇到的一些与url参数部分和锚部分相关的问题以及自己的解决方案。各位大佬如果有更好解决方案,欢迎留言指导交流。
推荐文章
好文我在看????
上一篇: php--Final关键字
下一篇: adodb与adodb_lite之比较
推荐阅读
-
vue vue-Router默认hash模式修改为history需要做的修改详解
-
vue-router中的hash和history两种模式的区别
-
vue2.0 路由模式mode="history"的作用
-
Vue单页式应用(Hash模式下)实现微信分享的实例
-
Vue路由history模式解决404问题的几种方法
-
3种vue路由传参的基本模式
-
vue vue-Router默认hash模式修改为history需要做的修改详解
-
详解Vue路由History mode模式中页面无法渲染的原因及解决
-
VUE的history模式下除了index外其他路由404报错解决办法
-
vue router嵌套路由在history模式下刷新无法渲染页面问题的解决方法