vueRouter push问题的思考
Posted littleWang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vueRouter push问题的思考相关的知识,希望对你有一定的参考价值。
背景
在开发vue的前端项目中,我们常常使用编程式路由来完成导航页面的切换。大家基本上都会使用到this.$router.push的方法。
常见的使用方法是:
this.$router.push({name:\'a\'});
this.$router.push({path:\'/a\'})
在项目的开发过程中,我使用了push方法采用上面的第二种方式,但是我书写的方式并没有带\'/\',我当时的路由假设为\'/a\',执行下面的方法,我的页面切换为\'/b\',这和我们一般书写的方式不一致,但是路径跳转是正常的。
this.$router.push({path:\'b\'})
研究阶段
我想知道path匹配的方式是带有\'/\'是从根路由开始替换的,但是如果我不带\'/\',为什么一切正常?我查询了官方文档,官方同样也有不带\'/\'的写法,但是并没有解释其中具体的逻辑。
于是我就去看了官方的源码。
顺着push方法一路找下去,我发现了一个方法utils/path.js有一个处理路径的方式:
resolvePath
export function resolvePath (
relative: string,
base: string,
append?: boolean
): string {
const firstChar = relative.charAt(0)
if (firstChar === \'/\') {
return relative
}
if (firstChar === \'?\' || firstChar === \'#\') {
return base + relative
}
const stack = base.split(\'/\')
// remove trailing segment if:
// - not appending
// - appending to trailing slash (last segment is empty)
if (!append || !stack[stack.length - 1]) {
stack.pop()
}
// resolve relative path
const segments = relative.replace(/^\\//, \'\').split(\'/\')
for (let i = 0; i < segments.length; i++) {
const segment = segments[i]
if (segment === \'..\') {
stack.pop()
} else if (segment !== \'.\') {
stack.push(segment)
}
}
// ensure leading slash
if (stack[0] !== \'\') {
stack.unshift(\'\')
}
return stack.join(\'/\')
}
我传入的path路径在这里得到了解析,然后恢复正常了。
后来我在官方编写的测试用例中看到了这个方法的测试代码。
describe(\'Path utils\', () => {
describe(\'resolvePath\', () => {
it(\'absolute\', () => {
const path = resolvePath(\'/a\', \'/b\')
expect(path).toBe(\'/a\')
})
it(\'relative\', () => {
const path = resolvePath(\'c/d\', \'/b\')
expect(path).toBe(\'/c/d\')
})
it(\'relative with append\', () => {
const path = resolvePath(\'c/d\', \'/b\', true)
expect(path).toBe(\'/b/c/d\')
})
it(\'relative parent\', () => {
const path = resolvePath(\'../d\', \'/a/b/c\')
expect(path).toBe(\'/a/d\')
})
it(\'relative parent with append\', () => {
const path = resolvePath(\'../d\', \'/a/b/c\', true)
expect(path).toBe(\'/a/b/d\')
})
it(\'relative query\', () => {
const path = resolvePath(\'?foo=bar\', \'/a/b\')
expect(path).toBe(\'/a/b?foo=bar\')
})
it(\'relative hash\', () => {
const path = resolvePath(\'#hi\', \'/a/b\')
expect(path).toBe(\'/a/b#hi\')
})
})
...
})
结合实际代码和测试用例我们发现:
当我们的原路径为/a,当我们push({path:b}),最终为生成\'/b\'
当我们的原路径为/a/c,当我们push({path:b}),最终为生成\'/a/b\'
当然还有其他各种情况,但是解决了我对于路径当前跳转的疑惑。大家有兴趣也可以试试别的方式。\'../b\'等方式,但是官方文档上并没有标出这些使用方式,所以大家还是尽量按照标准的方式。
希望可以解决大家对于官方文档上path前不带\'/\'的具体问题。
以上是关于vueRouter push问题的思考的主要内容,如果未能解决你的问题,请参考以下文章
Vue-Router 源码分析 VueRouter.push()的详解
$router.push跳转到登陆页,会再次触发当前页的请求?
this.$router.push页面不跳转 -- 记一个糊涂的 Bug,排查了好久
git项目初次push提示error: failed to push some refs to https://gitee.com/xxxx/gittest.git’解决方案 --九五小庞(代码片段