提交 | 用户 | age
|
e12c58
|
1 |
import type { RouteLocationNormalized, RouteRecordNormalized } from 'vue-router'; |
92cc60
|
2 |
import type { App, Component } from 'vue'; |
55e9d9
|
3 |
|
a305e5
|
4 |
import { unref } from 'vue'; |
4c63b1
|
5 |
import { isArray, isObject } from '/@/utils/is'; |
4418ec
|
6 |
import { cloneDeep, isEqual, mergeWith, unionWith } from 'lodash-es'; |
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 |
/** |
KL |
37 |
|
|
38 |
递归合并两个对象。 |
|
39 |
Recursively merge two objects. |
|
40 |
@param target 目标对象,合并后结果存放于此。The target object to merge into. |
|
41 |
@param source 要合并的源对象。The source object to merge from. |
|
42 |
@returns 合并后的对象。The merged object. |
|
43 |
*/ |
|
44 |
export function deepMerge<T extends object | null | undefined, U extends object | null | undefined>( |
|
45 |
target: T, |
|
46 |
source: U, |
|
47 |
): T & U { |
|
48 |
return mergeWith(cloneDeep(target), source, (objValue, srcValue) => { |
|
49 |
if (isObject(objValue) && isObject(srcValue)) { |
|
50 |
return mergeWith(cloneDeep(objValue), srcValue, (prevValue, nextValue) => { |
4418ec
|
51 |
// 如果是数组,合并数组(去重) If it is an array, merge the array (remove duplicates) |
CS |
52 |
return isArray(prevValue) ? unionWith(prevValue, nextValue, isEqual) : undefined; |
4c63b1
|
53 |
}); |
KL |
54 |
} |
|
55 |
}); |
2f6253
|
56 |
} |
陈 |
57 |
|
ba068b
|
58 |
export function openWindow( |
V |
59 |
url: string, |
56a966
|
60 |
opt?: { target?: TargetContext | string; noopener?: boolean; noreferrer?: boolean }, |
ba068b
|
61 |
) { |
V |
62 |
const { target = '__blank', noopener = true, noreferrer = true } = opt || {}; |
|
63 |
const feature: string[] = []; |
|
64 |
|
|
65 |
noopener && feature.push('noopener=yes'); |
|
66 |
noreferrer && feature.push('noreferrer=yes'); |
|
67 |
|
|
68 |
window.open(url, target, feature.join(',')); |
|
69 |
} |
a305e5
|
70 |
|
V |
71 |
// dynamic use hook props |
92cc60
|
72 |
export function getDynamicProps<T extends Record<string, unknown>, U>(props: T): Partial<U> { |
a305e5
|
73 |
const ret: Recordable = {}; |
V |
74 |
|
|
75 |
Object.keys(props).map((key) => { |
|
76 |
ret[key] = unref((props as Recordable)[key]); |
|
77 |
}); |
|
78 |
|
|
79 |
return ret as Partial<U>; |
144ab5
|
80 |
} |
581007
|
81 |
|
e12c58
|
82 |
export function getRawRoute(route: RouteLocationNormalized): RouteLocationNormalized { |
V |
83 |
if (!route) return route; |
|
84 |
const { matched, ...opt } = route; |
|
85 |
return { |
|
86 |
...opt, |
|
87 |
matched: (matched |
|
88 |
? matched.map((item) => ({ |
|
89 |
meta: item.meta, |
|
90 |
name: item.name, |
|
91 |
path: item.path, |
|
92 |
})) |
|
93 |
: undefined) as RouteRecordNormalized[], |
|
94 |
}; |
|
95 |
} |
55e9d9
|
96 |
|
92cc60
|
97 |
// https://github.com/vant-ui/vant/issues/8302 |
L |
98 |
type EventShim = { |
|
99 |
new (...args: any[]): { |
|
100 |
$props: { |
|
101 |
onClick?: (...args: any[]) => void; |
|
102 |
}; |
|
103 |
}; |
|
104 |
}; |
|
105 |
|
|
106 |
export type WithInstall<T> = T & { |
|
107 |
install(app: App): void; |
|
108 |
} & EventShim; |
|
109 |
|
|
110 |
export type CustomComponent = Component & { displayName?: string }; |
|
111 |
|
|
112 |
export const withInstall = <T extends CustomComponent>(component: T, alias?: string) => { |
|
113 |
(component as Record<string, unknown>).install = (app: App) => { |
|
114 |
const compName = component.name || component.displayName; |
|
115 |
if (!compName) return; |
|
116 |
app.component(compName, component); |
55e9d9
|
117 |
if (alias) { |
V |
118 |
app.config.globalProperties[alias] = component; |
|
119 |
} |
|
120 |
}; |
92cc60
|
121 |
return component as WithInstall<T>; |
55e9d9
|
122 |
}; |