y-admin-ui 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/utils/core.ts +45 -0
- package/lib/utils/directives/click-outside/index.ts +106 -0
- package/lib/utils/index.ts +142 -0
- package/lib/utils/printer.ts +997 -0
- package/lib/utils/vue/props/runtime.ts +3 -0
- package/lib/utils/vue/typescript.ts +1 -0
- package/lib/y-admin-ui.js +1487 -1569
- package/lib/y-admin-ui.js.gz +0 -0
- package/lib/y-admin-ui.umd.cjs +14 -14
- package/package.json +1 -1
@@ -0,0 +1,45 @@
|
|
1
|
+
/**
|
2
|
+
* 遍历children形式数据
|
3
|
+
* @param data 需要遍历的数据
|
4
|
+
* @param callback 回调
|
5
|
+
* @param childrenField children字段名
|
6
|
+
*/
|
7
|
+
export function eachTreeData(
|
8
|
+
data: any[],
|
9
|
+
callback: Function,
|
10
|
+
childrenField = 'children',
|
11
|
+
parent: any = ''
|
12
|
+
) {
|
13
|
+
if (data) {
|
14
|
+
data.forEach((d, i) => {
|
15
|
+
if (
|
16
|
+
callback &&
|
17
|
+
callback(d, i, parent) !== false &&
|
18
|
+
d[childrenField]?.length
|
19
|
+
) {
|
20
|
+
eachTreeData(d[childrenField], callback, childrenField, d);
|
21
|
+
}
|
22
|
+
});
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* 生成随机字符串
|
28
|
+
* @param length 长度
|
29
|
+
* @param radix 基数
|
30
|
+
*/
|
31
|
+
export function uuid(length = 32, radix: any) {
|
32
|
+
const num = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
33
|
+
let result = '';
|
34
|
+
for (let i = 0; i < length; i++) {
|
35
|
+
result += num.charAt(Math.floor(Math.random() * (radix || num.length)));
|
36
|
+
}
|
37
|
+
return result;
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* 获取屏幕宽度
|
42
|
+
*/
|
43
|
+
export function screenWidth() {
|
44
|
+
return document.documentElement.clientWidth || document.body.clientWidth;
|
45
|
+
}
|
@@ -0,0 +1,106 @@
|
|
1
|
+
import { isClient } from "@vueuse/core"
|
2
|
+
|
3
|
+
import type { ComponentPublicInstance, DirectiveBinding, ObjectDirective } from "vue"
|
4
|
+
|
5
|
+
type DocumentHandler = <T extends MouseEvent>(mouseup: T, mousedown: T) => void
|
6
|
+
type FlushList = Map<
|
7
|
+
HTMLElement,
|
8
|
+
{
|
9
|
+
documentHandler: DocumentHandler
|
10
|
+
bindingFn: (...args: unknown[]) => unknown
|
11
|
+
}[]
|
12
|
+
>
|
13
|
+
|
14
|
+
const nodeList: FlushList = new Map()
|
15
|
+
|
16
|
+
let startClick: MouseEvent
|
17
|
+
|
18
|
+
if (isClient) {
|
19
|
+
document.addEventListener("mousedown", (e: MouseEvent) => (startClick = e))
|
20
|
+
document.addEventListener("mouseup", (e: MouseEvent) => {
|
21
|
+
for (const handlers of nodeList.values()) {
|
22
|
+
for (const { documentHandler } of handlers) {
|
23
|
+
documentHandler(e as MouseEvent, startClick)
|
24
|
+
}
|
25
|
+
}
|
26
|
+
})
|
27
|
+
}
|
28
|
+
|
29
|
+
function createDocumentHandler(el: HTMLElement, binding: DirectiveBinding): DocumentHandler {
|
30
|
+
let excludes: HTMLElement[] = []
|
31
|
+
if (Array.isArray(binding.arg)) {
|
32
|
+
excludes = binding.arg
|
33
|
+
} else if ((binding.arg as unknown) instanceof HTMLElement) {
|
34
|
+
// due to current implementation on binding type is wrong the type casting is necessary here
|
35
|
+
excludes.push(binding.arg as unknown as HTMLElement)
|
36
|
+
}
|
37
|
+
return function (mouseup, mousedown) {
|
38
|
+
const popperRef = (
|
39
|
+
binding.instance as ComponentPublicInstance<{
|
40
|
+
popperRef: HTMLElement
|
41
|
+
}>
|
42
|
+
).popperRef
|
43
|
+
const mouseUpTarget = mouseup.target as Node
|
44
|
+
const mouseDownTarget = mousedown?.target as Node
|
45
|
+
const isBound = !binding || !binding.instance
|
46
|
+
const isTargetExists = !mouseUpTarget || !mouseDownTarget
|
47
|
+
const isContainedByEl = el.contains(mouseUpTarget) || el.contains(mouseDownTarget)
|
48
|
+
const isSelf = el === mouseUpTarget
|
49
|
+
|
50
|
+
const isTargetExcluded =
|
51
|
+
(excludes.length && excludes.some(item => item?.contains(mouseUpTarget))) ||
|
52
|
+
(excludes.length && excludes.includes(mouseDownTarget as HTMLElement))
|
53
|
+
const isContainedByPopper =
|
54
|
+
popperRef && (popperRef.contains(mouseUpTarget) || popperRef.contains(mouseDownTarget))
|
55
|
+
if (
|
56
|
+
isBound ||
|
57
|
+
isTargetExists ||
|
58
|
+
isContainedByEl ||
|
59
|
+
isSelf ||
|
60
|
+
isTargetExcluded ||
|
61
|
+
isContainedByPopper
|
62
|
+
) {
|
63
|
+
return
|
64
|
+
}
|
65
|
+
binding.value(mouseup, mousedown)
|
66
|
+
}
|
67
|
+
}
|
68
|
+
|
69
|
+
const ClickOutside: ObjectDirective = {
|
70
|
+
beforeMount(el: HTMLElement, binding: DirectiveBinding) {
|
71
|
+
// there could be multiple handlers on the element
|
72
|
+
if (!nodeList.has(el)) {
|
73
|
+
nodeList.set(el, [])
|
74
|
+
}
|
75
|
+
|
76
|
+
nodeList.get(el)!.push({
|
77
|
+
documentHandler: createDocumentHandler(el, binding),
|
78
|
+
bindingFn: binding.value
|
79
|
+
})
|
80
|
+
},
|
81
|
+
updated(el: HTMLElement, binding: DirectiveBinding) {
|
82
|
+
if (!nodeList.has(el)) {
|
83
|
+
nodeList.set(el, [])
|
84
|
+
}
|
85
|
+
|
86
|
+
const handlers = nodeList.get(el)!
|
87
|
+
const oldHandlerIndex = handlers.findIndex(item => item.bindingFn === binding.oldValue)
|
88
|
+
const newHandler = {
|
89
|
+
documentHandler: createDocumentHandler(el, binding),
|
90
|
+
bindingFn: binding.value
|
91
|
+
}
|
92
|
+
|
93
|
+
if (oldHandlerIndex >= 0) {
|
94
|
+
// replace the old handler to the new handler
|
95
|
+
handlers.splice(oldHandlerIndex, 1, newHandler)
|
96
|
+
} else {
|
97
|
+
handlers.push(newHandler)
|
98
|
+
}
|
99
|
+
},
|
100
|
+
unmounted(el: HTMLElement) {
|
101
|
+
// remove all listeners when a component unmounted
|
102
|
+
nodeList.delete(el)
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
export default ClickOutside
|
@@ -0,0 +1,142 @@
|
|
1
|
+
type Func = (...args: any[]) => any
|
2
|
+
/**
|
3
|
+
* 防抖函数
|
4
|
+
* @param { Function } func 函数
|
5
|
+
* @param { Number } delay 防抖时间
|
6
|
+
* @param { Boolean } immediate 是否立即执行
|
7
|
+
* @param { Function } resultCallback
|
8
|
+
*/
|
9
|
+
export function debounce(
|
10
|
+
func: Func,
|
11
|
+
delay: number = 500,
|
12
|
+
immediate?: boolean,
|
13
|
+
resultCallback?: Func
|
14
|
+
) {
|
15
|
+
let timer: null | ReturnType<typeof setTimeout> = null
|
16
|
+
let isInvoke = false
|
17
|
+
const _debounce = function (this: unknown, ...args: any[]) {
|
18
|
+
return new Promise((resolve, reject) => {
|
19
|
+
if (timer) clearTimeout(timer)
|
20
|
+
if (immediate && !isInvoke) {
|
21
|
+
try {
|
22
|
+
const result = func.apply(this, args)
|
23
|
+
if (resultCallback) resultCallback(result)
|
24
|
+
resolve(result)
|
25
|
+
} catch (e) {
|
26
|
+
reject(e)
|
27
|
+
}
|
28
|
+
isInvoke = true
|
29
|
+
} else {
|
30
|
+
timer = setTimeout(() => {
|
31
|
+
try {
|
32
|
+
const result = func.apply(this, args)
|
33
|
+
if (resultCallback) resultCallback(result)
|
34
|
+
resolve(result)
|
35
|
+
} catch (e) {
|
36
|
+
reject(e)
|
37
|
+
}
|
38
|
+
isInvoke = false
|
39
|
+
timer = null
|
40
|
+
}, delay)
|
41
|
+
}
|
42
|
+
})
|
43
|
+
}
|
44
|
+
_debounce.cancel = function () {
|
45
|
+
if (timer) clearTimeout(timer)
|
46
|
+
isInvoke = false
|
47
|
+
timer = null
|
48
|
+
}
|
49
|
+
return _debounce
|
50
|
+
}
|
51
|
+
|
52
|
+
/**
|
53
|
+
* 节流函数
|
54
|
+
* @param { Function } func
|
55
|
+
* @param { Boolean } interval
|
56
|
+
* @param { Object } options
|
57
|
+
* leading:初始 trailing:结尾
|
58
|
+
*/
|
59
|
+
export function throttle(
|
60
|
+
func: Func,
|
61
|
+
interval: number,
|
62
|
+
options = { leading: false, trailing: true }
|
63
|
+
) {
|
64
|
+
let timer: null | ReturnType<typeof setTimeout> = null
|
65
|
+
let lastTime = 0
|
66
|
+
const { leading, trailing } = options
|
67
|
+
const _throttle = function (this: unknown, ...args: any[]) {
|
68
|
+
const nowTime = Date.now()
|
69
|
+
if (!lastTime && !leading) lastTime = nowTime
|
70
|
+
const remainTime = interval - (nowTime - lastTime)
|
71
|
+
if (remainTime <= 0) {
|
72
|
+
if (timer) {
|
73
|
+
clearTimeout(timer)
|
74
|
+
timer = null
|
75
|
+
}
|
76
|
+
lastTime = nowTime
|
77
|
+
func.apply(this, args)
|
78
|
+
}
|
79
|
+
if (trailing && !timer) {
|
80
|
+
timer = setTimeout(() => {
|
81
|
+
lastTime = !leading ? 0 : Date.now()
|
82
|
+
timer = null
|
83
|
+
func.apply(this, args)
|
84
|
+
}, remainTime)
|
85
|
+
}
|
86
|
+
}
|
87
|
+
_throttle.cancel = function () {
|
88
|
+
if (timer) clearTimeout(timer)
|
89
|
+
timer = null
|
90
|
+
lastTime = 0
|
91
|
+
}
|
92
|
+
return _throttle
|
93
|
+
}
|
94
|
+
|
95
|
+
/**
|
96
|
+
* 驼峰转换下划线
|
97
|
+
* @param { String } name
|
98
|
+
*/
|
99
|
+
export function toLine(name: string) {
|
100
|
+
return name.replace(/([A-Z])/g, "_$1").toLowerCase()
|
101
|
+
}
|
102
|
+
|
103
|
+
/*
|
104
|
+
自定义保留 precision 位小数,并使用 separator 分隔符进行数字格式化
|
105
|
+
value:格式化目标数字
|
106
|
+
precision:精度,保留小数点后几位,默认2位
|
107
|
+
separator:千分位分隔符,默认为','
|
108
|
+
decimal:小数点符号,默认'.'
|
109
|
+
prefix:前缀字符,默认''
|
110
|
+
suffix:后缀字符,默认''
|
111
|
+
formatNumber(123456789.87654321, 2, ',') // 123,456,789.88
|
112
|
+
*/
|
113
|
+
export function formatNumber(
|
114
|
+
value: number | string,
|
115
|
+
precision = 2,
|
116
|
+
separator = ",",
|
117
|
+
decimal = ".",
|
118
|
+
prefix = "",
|
119
|
+
suffix = ""
|
120
|
+
): string {
|
121
|
+
if (Number(value) === 0) {
|
122
|
+
return Number(value).toFixed(precision)
|
123
|
+
}
|
124
|
+
if (!value) {
|
125
|
+
return ""
|
126
|
+
}
|
127
|
+
value = Number(value).toFixed(precision)
|
128
|
+
value += ""
|
129
|
+
const nums = value.split(".")
|
130
|
+
let integer = nums[0]
|
131
|
+
const decimals = nums.length > 1 ? decimal + nums[1] : ""
|
132
|
+
const reg = /(\d+)(\d{3})/
|
133
|
+
function isNumber(value: any) {
|
134
|
+
return Object.prototype.toString.call(value) === "[object Number]"
|
135
|
+
}
|
136
|
+
if (separator && !isNumber(separator)) {
|
137
|
+
while (reg.test(integer)) {
|
138
|
+
integer = integer.replace(reg, "$1" + separator + "$2")
|
139
|
+
}
|
140
|
+
}
|
141
|
+
return prefix + integer + decimals + suffix
|
142
|
+
}
|