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.
@@ -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
+ }