背景
在开发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前不带'/'的具体问题。