# uniapp封装路由跳转
封装的好处是方便进行参数和跳转控制
/**
* 移除对象属性
* @params obj 对象。 Object
* @params formitFn 自定义对数据格式化。(key:string,value:obj[key]):any=>newValue
* @params emptyTypes 自定义需要移除的值,默认为[null, undefined, '',{},[]]。 any[]
* @return 处理后的对象。Object
*/
export const removeEmptyObjParams = (
obj,
formitFn = (_key, value) => value,
emptyTypes = [null, undefined, {}, [], ""]
) => {
return Object.keys(obj)
.filter(
(key) =>
!emptyTypes.some((item) => {
return typeof item === "object" && item !== null
? JSON.stringify(item) === JSON.stringify(obj[key])
: item === obj[key];
})
)
.reduce((acc, key) => ({ ...acc, [key]: formitFn(key, obj[key]) }), {});
};
/**
* 获取指定链接的参数,默认当前页面链接(注意,小程序中要在页面初始化后才能稳定获取到相关信息:App.onShow()之后/页面onLoad之后)
*/
export const getUrlParamBySearch = ({ name, path = "", decode = true } = {}) => {
const pages = getCurrentPages();
const currentPage = pages.slice(-1)[0] || {};
const _path = path || currentPage.$page?.fullPath || location?.href || "";
// 分组捕获 两个子组
const reg = /([^?&=]+)=([^&]+)/g;
let params = {};
_path.replace(reg, (_, k, v) => {
// 为什么要解码两次?因为 uniapp 跳转时会对特殊字符进行一次编码(哪怕是你 encodeURIComponent 后产生的特殊字符)
params[k] = decode ? decodeURIComponent(decodeURIComponent(v)) : v;
});
return name ? Reflect.get(params, name) : params;
};
/**
* 对象转换为url参数
* @example obj2Params({a: 1, b: 2}) // a=1&b=2
*/
export const objToParams = (obj) => {
return Object.keys(obj)
.filter((k) => {
return obj[k] !== "";
})
.map((v) => {
return `${v}=${obj[v]}`;
})
.join("&");
};
/**
* 构建path路径
*/
export const buildPath = (path, obj) => {
const hasQuesMark = path.indexOf("?") > -1;
const linkMark = hasQuesMark ? "&" : "?";
const params = objToParams(removeEmptyObjParams(obj));
return params ? `${path}${linkMark}${params}` : path;
};
export function routerTo(path, params = {}, options = {}) {
const { redirect = false, reLaunch = false } = options;
const pages = getCurrentPages();
// 提取路径中自带的参数,为了路径中参数和传入参数去重处理
const pageParams = getUrlParamBySearch({ path, decode: false });
const _params = removeEmptyObjParams({ ...pageParams, ...params });
const pagePath = path.split("?")[0];
// 如果路由栈长度超过9,清空路由栈(小程序限制路由栈最大为10)
const isLimtiPagesLength = pages.length > 9;
const data = {
url: buildPath(pagePath, _params),
};
if (redirect || isLimtiPagesLength) {
uni.redirectTo(data);
return;
}
if (reLaunch) {
uni.reLaunch(data);
return;
}
uni.navigateTo(data);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96