export const valueSeparator = '~' export const paramSeparator = ',' export const queryFlag = 'q=' export const queryPattern = new RegExp(queryFlag + '.*' + paramSeparator) /** * 转换query对象成可附在url上的字符串 * qs.stringify只能自定义delimiter,不能自定义equal * {a: 'a&b', b: true} => 'a~a%26b,b~true' * * @param {object} query * @param {string} equal - 键和值的分隔符 * @param {string} delimiter - 键值对之间的分隔符 * @return {string} */ export function stringify( query, equal = valueSeparator, delimiter = paramSeparator ) { return Object.keys(query) .map(k => `${k}${equal}${encodeURIComponent(query[k])}`) .join(delimiter) } /** * 转换附在url上的字符串成query对象 * qs.parse只能自定义delimiter,不能自定义equal * 'a~a%26b,b~true' => {a: 'a&b', b: true} * * @param {string} query * @param {string} equal - 键和值的分隔符 * @param {string} delimiter - 键值对之间的分隔符 * @return {object} */ export function parse( query, equal = valueSeparator, delimiter = paramSeparator ) { return query .split(delimiter) .map(param => param.split(equal)) .reduce((obj, [k, v]) => { obj[k] = decodeURIComponent(v) return obj }, {}) } /** * 将query对象转换成str插入到url上 * * @param {string} url * @param {object} query * @param {'history'|'hash'} routerMode * @returns {string} 插入了query的url */ export function set(url, query, routerMode) { const queryStr = queryFlag + stringify(query) + paramSeparator const queryPrefix = str => (str.indexOf('?') > -1 ? '&' : '?') if (queryPattern.test(url)) { return url.replace(queryPattern, queryStr) } else if (url.indexOf('#') === -1) { return url + queryPrefix(url) + queryStr } else { const [path, hash] = url.split('#') if (routerMode === 'history') { return path + queryPrefix(path) + queryStr + '#' + hash } else { return url + queryPrefix(hash) + queryStr } } } /** * 从url中取出query对象,如果没有,返回null * * @param {string} url * @return {object|null} 对象类型的query参数 */ export function get(url) { const found = url.match(queryPattern) if (!found) return null const queryStr = found[0].replace(queryFlag, '').slice(0, -1) // 移除末尾的paramSeparator return parse(queryStr) } /** * 从url中移除(?||&)queryPattern * @param {string} url */ export function clear(url) { if (queryPattern.test(url)) { const replacePattern = RegExp('[?&]' + queryPattern.source) return url.replace(replacePattern, '') } else { return url } }