/* @flow */
/**
* resolvePath(): 解析路径
* 第一个参数: 相对路径,要跳转路径的 pathname。
* 第二个参数: 基准路径。
* 第三个参数: 是否需要拼接基准地址。
*/
export function resolvePath(
relative: string,
base: string,
append?: boolean
): string {
//判断 relative 是否是以 “/” 开头。
const firstChar = relative.charAt(0)
if (firstChar === '/') {
//如果是,则认为是绝对路径,不需要拼接基准路径。
return relative
}
//如果以 ? 或者 # 开头,则表示要跳转的路径是 "",则表示是原路径跳转,即刷新本页面。
// 所以拼接原来路径的 pathName。
if (firstChar === '?' || firstChar === '#') {
return base + relative
}
/*
下面的路径是相对路径的情形
*/
//将 base 路径按照 "/" 切分成数组。
const stack = base.split('/')
// remove trailing segment if:
// - not appending
// - appending to trailing slash (last segment is empty)
//如果需要追加基础路径,且 stack 最后一个元素为 “”,则将最后一个元素移除。
if (!append || !stack[stack.length - 1]) {
stack.pop()
}
//relative.replace(/^\//, ''): 去除开头的第一个 /.
//然后按照 ‘/’ 进行切割成数组。
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 中。
stack.push(segment)
}
}
//之所以要添加一个 '' 在数组的队首,是为了保证 stack.join('/') 是, 是 "" + “/” +... 的情形。
//即字符串以 “/”开头。
if (stack[0] !== '') {
stack.unshift('')
}
//含有路径信息的数组,转为 “/” 间隔的字符串形式。
return stack.join('/')
}
/*
parsePath(): 拆分路径,解析成一个 { path, query, hash } 的对象。
第一个参数: path 是 location.url; 或者 this.$router.push("/user/info?name=mengze#a",{ query: {xxx} } )
中的 /user/info?name=mengze#a 这一部分内容。
*/
export function parsePath(path: string): {
path: string,
query: string,
hash: string,
} {
let hash = ''
let query = ''
//举一个路径的例子: /user/info?name=mengze&age=18#aaa
//判断 path 上是否有 # 号
const hashIndex = path.indexOf('#')
//如果存在 # 号,则将 # 后面的内容记录为 hash。 且将 path 去除 # 之后的内容。
if (hashIndex >= 0) {
hash = path.slice(hashIndex)
path = path.slice(0, hashIndex)
}
//判断 path 上是否有 ?号
const queryIndex = path.indexOf('?')
//如果存在 ? 号。。
if (queryIndex >= 0) {
//则将 ? 后面的内容记录为 query string
query = path.slice(queryIndex + 1)
//将 path 含有的 ?以及后面的字符串都去掉。保存的内容只有 window.location.href.pathname 部分。
path = path.slice(0, queryIndex)
}
/*
将 path 路径解析为一个 pathName, query,hash 分离的对象。此时的 query 还是个字符串。
*/
return {
path,
query,
hash,
}
}
/**
* 清理 path 路径中 // 的情形。
*/
export function cleanPath(path: string): string {
//如果路径中存在连续的多个//,那么替换为只有一个 /。
return path.replace(/\/+/g, '/')
}
vue-router3 源码注释系列 /src/util/path.js
最新推荐文章于 2023-06-17 09:46:16 发布