提交 | 用户 | age
|
7ca007
|
1 |
import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'; |
9c43c7
|
2 |
import type { App, Component } from 'vue'; |
55e9d9
|
3 |
|
c516d3
|
4 |
import { intersectionWith, isEqual, mergeWith, unionWith } from 'lodash-es'; |
a305e5
|
5 |
import { unref } from 'vue'; |
4c63b1
|
6 |
import { isArray, isObject } from '/@/utils/is'; |
e12c58
|
7 |
|
35d2bf
|
8 |
export const noop = () => {}; |
8a9ca4
|
9 |
|
2f6253
|
10 |
/** |
陈 |
11 |
* @description: Set ui mount node |
|
12 |
*/ |
|
13 |
export function getPopupContainer(node?: HTMLElement): HTMLElement { |
116a1f
|
14 |
return (node?.parentNode as HTMLElement) ?? document.body; |
2f6253
|
15 |
} |
ba068b
|
16 |
|
2f6253
|
17 |
/** |
陈 |
18 |
* Add the object as a parameter to the URL |
|
19 |
* @param baseUrl url |
|
20 |
* @param obj |
|
21 |
* @returns {string} |
|
22 |
* eg: |
|
23 |
* let obj = {a: '3', b: '4'} |
|
24 |
* setObjToUrlParams('www.baidu.com', obj) |
|
25 |
* ==>www.baidu.com?a=3&b=4 |
|
26 |
*/ |
|
27 |
export function setObjToUrlParams(baseUrl: string, obj: any): string { |
|
28 |
let parameters = ''; |
|
29 |
for (const key in obj) { |
|
30 |
parameters += key + '=' + encodeURIComponent(obj[key]) + '&'; |
|
31 |
} |
|
32 |
parameters = parameters.replace(/&$/, ''); |
da0491
|
33 |
return /\?$/.test(baseUrl) ? baseUrl + parameters : baseUrl.replace(/\/?$/, '?') + parameters; |
2f6253
|
34 |
} |
陈 |
35 |
|
4c63b1
|
36 |
/** |
c516d3
|
37 |
* Recursively merge two objects. |
KL |
38 |
* 递归合并两个对象。 |
|
39 |
* |
|
40 |
* @param source The source object to merge from. 要合并的源对象。 |
|
41 |
* @param target The target object to merge into. 目标对象,合并后结果存放于此。 |
|
42 |
* @param mergeArrays How to merge arrays. Default is "replace". |
|
43 |
* 如何合并数组。默认为replace。 |
|
44 |
* - "union": Union the arrays. 对数组执行并集操作。 |
|
45 |
* - "intersection": Intersect the arrays. 对数组执行交集操作。 |
|
46 |
* - "concat": Concatenate the arrays. 连接数组。 |
|
47 |
* - "replace": Replace the source array with the target array. 用目标数组替换源数组。 |
|
48 |
* @returns The merged object. 合并后的对象。 |
4c63b1
|
49 |
*/ |
KL |
50 |
export function deepMerge<T extends object | null | undefined, U extends object | null | undefined>( |
c516d3
|
51 |
source: T, |
KL |
52 |
target: U, |
|
53 |
mergeArrays: 'union' | 'intersection' | 'concat' | 'replace' = 'replace', |
4c63b1
|
54 |
): T & U { |
c516d3
|
55 |
if (!target) { |
KL |
56 |
return source as T & U; |
|
57 |
} |
|
58 |
if (!source) { |
|
59 |
return target as T & U; |
|
60 |
} |
7535db
|
61 |
return mergeWith({}, source, target, (sourceValue, targetValue) => { |
KL |
62 |
if (isArray(targetValue) && isArray(sourceValue)) { |
|
63 |
switch (mergeArrays) { |
|
64 |
case 'union': |
|
65 |
return unionWith(sourceValue, targetValue, isEqual); |
|
66 |
case 'intersection': |
|
67 |
return intersectionWith(sourceValue, targetValue, isEqual); |
|
68 |
case 'concat': |
|
69 |
return sourceValue.concat(targetValue); |
|
70 |
case 'replace': |
|
71 |
return targetValue; |
|
72 |
default: |
|
73 |
throw new Error(`Unknown merge array strategy: ${mergeArrays as string}`); |
|
74 |
} |
4c63b1
|
75 |
} |
7535db
|
76 |
if (isObject(targetValue) && isObject(sourceValue)) { |
KL |
77 |
return deepMerge(sourceValue, targetValue, mergeArrays); |
|
78 |
} |
|
79 |
return undefined; |
|
80 |
}); |
2f6253
|
81 |
} |
陈 |
82 |
|
ba068b
|
83 |
export function openWindow( |
V |
84 |
url: string, |
56a966
|
85 |
opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean }, |
ba068b
|
86 |
) { |
V |
87 |
const { target = '__blank', noopener = true, noreferrer = true } = opt || {}; |
|
88 |
const feature: string[] = []; |
|
89 |
|
|
90 |
noopener && feature.push('noopener=yes'); |
|
91 |
noreferrer && feature.push('noreferrer=yes'); |
|
92 |
|
|
93 |
window.open(url, target, feature.join(',')); |
|
94 |
} |
a305e5
|
95 |
|
V |
96 |
// dynamic use hook props |
92cc60
|
97 |
export function getDynamicProps<T extends Record<string, unknown>, U>(props: T): Partial<U> { |
a305e5
|
98 |
const ret: Recordable = {}; |
V |
99 |
|
|
100 |
Object.keys(props).map((key) => { |
|
101 |
ret[key] = unref((props as Recordable)[key]); |
|
102 |
}); |
|
103 |
|
|
104 |
return ret as Partial<U>; |
144ab5
|
105 |
} |
581007
|
106 |
|
e12c58
|
107 |
export function getRawRoute(route: RouteLocationNormalized): RouteLocationNormalized { |
V |
108 |
if (!route) return route; |
|
109 |
const { matched, ...opt } = route; |
|
110 |
return { |
|
111 |
...opt, |
|
112 |
matched: (matched |
|
113 |
? matched.map((item) => ({ |
|
114 |
meta: item.meta, |
|
115 |
name: item.name, |
|
116 |
path: item.path, |
|
117 |
})) |
|
118 |
: undefined) as RouteRecordNormalized[], |
|
119 |
}; |
|
120 |
} |
55e9d9
|
121 |
|
92cc60
|
122 |
// https://github.com/vant-ui/vant/issues/8302 |
L |
123 |
type EventShim = { |
|
124 |
new (...args: any[]): { |
|
125 |
$props: { |
|
126 |
onClick?: (...args: any[]) => void; |
|
127 |
}; |
|
128 |
}; |
|
129 |
}; |
|
130 |
|
|
131 |
export type WithInstall<T> = T & { |
|
132 |
install(app: App): void; |
|
133 |
} & EventShim; |
|
134 |
|
|
135 |
export type CustomComponent = Component & { displayName?: string }; |
|
136 |
|
|
137 |
export const withInstall = <T extends CustomComponent>(component: T, alias?: string) => { |
|
138 |
(component as Record<string, unknown>).install = (app: App) => { |
|
139 |
const compName = component.name || component.displayName; |
|
140 |
if (!compName) return; |
|
141 |
app.component(compName, component); |
55e9d9
|
142 |
if (alias) { |
V |
143 |
app.config.globalProperties[alias] = component; |
|
144 |
} |
|
145 |
}; |
92cc60
|
146 |
return component as WithInstall<T>; |
55e9d9
|
147 |
}; |