@qy_better_lib/core 0.0.1

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 @@
1
+ (function(r,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("element-plus")):typeof define=="function"&&define.amd?define(["exports","element-plus"],u):(r=typeof globalThis<"u"?globalThis:r||self,u(r["@qy-better-lib/core"]={},r["element-plus"]))})(this,function(r,u){"use strict";function M(){return Math.floor(Math.random()*1e4)}function k(e){return Math.floor(Math.random()*Math.floor(e))}function $(){const e=y;return`${e()}${e()}-${e()}-${e()}-${e()}-${e()}${e()}${e()}`}function y(){return Math.floor((1+Math.random())*65536).toString(16).substring(1)}function A(e){return e===void 0}function p(e){return Object.prototype.toString.call(e)==="[object Array]"}function g(e){return typeof e=="object"&&Object.prototype.toString.call(e)==="[object Object]"}function v(e){return Object.prototype.toString.call(e)==="[object Date]"}function B(e){return!e&&e!==0||p(e)&&e.length===0||g(e)&&!Object.keys(e).length}function h(e){return typeof Element>"u"?!1:e instanceof Element}const T=typeof window<"u",N=e=>typeof e=="number";function w(e,t="key",n="children"){const o={},i=(c,s)=>{for(let a=0;a<c.length;a++){const l=c[a],d=l[t];if(!o[d]){o[d]=l,s&&(o[d].parent=o[s]);const m=l[n];m&&m.length>0&&i(m,l[t])}}};return i(e),o}function H(e){return e?Object.prototype.toString.call(1)!=="[object Number]"?`${e}`:`${e}`.replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g,"$1,"):"0"}function F(){const e=localStorage.getItem("token");if(!e)return;const t=JSON.parse(e);if(t!==null)if(t.expirse!=null&&t.expirse<new Date().getTime())localStorage.removeItem("token");else return t.value;return null}function L(e,t){!t&&(t=7*24*60*60*1e3)||(t=t*1e3);const n={value:e,expirse:new Date().getTime()+t};localStorage.setItem("token",JSON.stringify(n))}function R(){localStorage.removeItem("token")}function U(e,t,n="local"){const o=n=="local"?localStorage:sessionStorage;t!=null&&o.setItem(e,JSON.stringify(t))}function _(e,t="local"){let o=(t=="local"?localStorage:sessionStorage).getItem(e);return o&&JSON.parse(o||"")}function b(e,t="local"){(t=="local"?localStorage:sessionStorage).removeItem(e)}function J(e="local"){(e=="local"?localStorage:sessionStorage).clear()}function j(e,t,n){const o={beforeClose:(i,c,s)=>{i==="confirm"?setTimeout(()=>{s()},0):s()},...n};u.ElMessageBox.confirm(`此操作将${e}, 是否继续?`,"提示",o).then(async()=>{t&&t()}).catch(()=>{})}function q(e,t,n){return new Promise((o,i)=>{const c={beforeClose:(s,a,l)=>{s==="confirm"?setTimeout(()=>{l()},0):l()},...n};u.ElMessageBox.confirm(`${e}`,"Tip",c).then(()=>{o(t&&t())}).catch(()=>{})})}function P(e,t="",n=!1,o=3e3){u.ElMessage({showClose:!0,message:t,type:e,duration:o,dangerouslyUseHTMLString:n})}function V(e,t="",n=!1,o="bottom-right",i=0){u.ElNotification({title:"消息通知",message:t,type:e,dangerouslyUseHTMLString:n,duration:i,showClose:!0,position:o})}function C(e){const t=Object.prototype.toString;if(!e||typeof e!="object")return e;if(e.nodeType&&"cloneNode"in e)return e.cloneNode(!0);if(t.call(e)==="[object Date]")return new Date(e.getTime());if(t.call(e)==="[object RegExp]"){const o=[];return e.global&&o.push("g"),e.multiline&&o.push("m"),e.ignoreCase&&o.push("i"),new RegExp(e.source,o.join(""))}if(t.call(e)==="[object FormData]"){const o=new FormData;for(const[i,c]of e.entries())o.append(i,c);return o}const n=Array.isArray(e)?[]:e.constructor?new e.constructor:{};for(const o in e)n[o]=C(e[o]);return n}function E(...e){let t=e.length,n=e[0];g(n)||(n={});for(let o=1;o<t;o++){let i=e[o];if(g(i))for(let c in i)c==="__proto__"||n===i[c]||(g(i[c])?n[c]=E(n[c],i[c]):n[c]=i[c])}return n}function O(e,t){return!e||e.tagName==="BODY"?null:e.classList.contains(t)?e:O(e.parentNode,t)}const f=new Map;let D;T&&(document.addEventListener("mousedown",e=>D=e),document.addEventListener("mouseup",e=>{for(const t of f.values())for(const{documentHandler:n}of t)n(e,D)}));function I(e,t){let n=[];return Array.isArray(t.arg)?n=t.arg:h(t.arg)&&n.push(t.arg),function(o,i){const c=t.instance.popperRef,s=o.target,a=i==null?void 0:i.target,l=!t||!t.instance,d=!s||!a,m=e.contains(s)||e.contains(a),z=e===s,G=n.length&&n.some(S=>S==null?void 0:S.contains(s))||n.length&&n.includes(a),K=c&&(c.contains(s)||c.contains(a));l||d||m||z||G||K||t.value(o,i)}}const Y={beforeMount(e,t){var n;f.has(e)||f.set(e,[]),(n=f.get(e))==null||n.push({documentHandler:I(e,t),bindingFn:t.value})},updated(e,t){f.has(e)||f.set(e,[]);const n=f.get(e),o=n==null?void 0:n.findIndex(c=>c.bindingFn===t.oldValue),i={documentHandler:I(e,t),bindingFn:t.value};o&&o>=0?n==null||n.splice(o,1,i):n==null||n.push(i)},unmounted(e){f.delete(e)}};r.ClickOutside=Y,r.clearStorage=J,r.confirmBox=j,r.confirmBoxAsync=q,r.deepAssign=E,r.deepClone=C,r.generateId=M,r.generateString=y,r.getParentByClass=O,r.getRandomInt=k,r.getStorage=_,r.getToken=F,r.guiID=$,r.isArray=p,r.isClient=T,r.isDate=v,r.isElement=h,r.isEmpty=B,r.isNumber=N,r.isObject=g,r.isUndefined=A,r.messageAlert=P,r.notification=V,r.removeStorage=b,r.removeToken=R,r.setStorage=U,r.setToken=L,r.thousandSeparator=H,r.treeFlat=w,Object.defineProperty(r,Symbol.toStringTag,{value:"Module"})});
@@ -0,0 +1,4 @@
1
+ import { ObjectDirective } from 'vue';
2
+
3
+ declare const ClickOutside: ObjectDirective;
4
+ export default ClickOutside;
@@ -0,0 +1,41 @@
1
+ import { isClient as E, isElement as H } from "../utils/is.js";
2
+ import "element-plus";
3
+ const s = /* @__PURE__ */ new Map();
4
+ let f;
5
+ E && (document.addEventListener("mousedown", (e) => f = e), document.addEventListener("mouseup", (e) => {
6
+ for (const n of s.values())
7
+ for (const { documentHandler: t } of n)
8
+ t(e, f);
9
+ }));
10
+ function d(e, n) {
11
+ let t = [];
12
+ return Array.isArray(n.arg) ? t = n.arg : H(n.arg) && t.push(n.arg), function(a, o) {
13
+ const c = n.instance.popperRef, r = a.target, u = o == null ? void 0 : o.target, l = !n || !n.instance, p = !r || !u, g = e.contains(r) || e.contains(u), m = e === r, v = t.length && t.some((i) => i == null ? void 0 : i.contains(r)) || t.length && t.includes(u), x = c && (c.contains(r) || c.contains(u));
14
+ l || p || g || m || v || x || n.value(a, o);
15
+ };
16
+ }
17
+ const T = {
18
+ beforeMount(e, n) {
19
+ var t;
20
+ s.has(e) || s.set(e, []), (t = s.get(e)) == null || t.push({
21
+ documentHandler: d(e, n),
22
+ bindingFn: n.value
23
+ });
24
+ },
25
+ updated(e, n) {
26
+ s.has(e) || s.set(e, []);
27
+ const t = s.get(e), a = t == null ? void 0 : t.findIndex(
28
+ (c) => c.bindingFn === n.oldValue
29
+ ), o = {
30
+ documentHandler: d(e, n),
31
+ bindingFn: n.value
32
+ };
33
+ a && a >= 0 ? t == null || t.splice(a, 1, o) : t == null || t.push(o);
34
+ },
35
+ unmounted(e) {
36
+ s.delete(e);
37
+ }
38
+ };
39
+ export {
40
+ T as default
41
+ };
@@ -0,0 +1,3 @@
1
+ import { default as ClickOutside } from './click-outside';
2
+
3
+ export { ClickOutside };
package/lib/index.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from './utils/index';
2
+ export * from './directives/index';
package/lib/index.js ADDED
@@ -0,0 +1,40 @@
1
+ import { generateId as t, generateString as o, getRandomInt as n, guiID as a } from "./utils/random.js";
2
+ import { isArray as s, isClient as m, isDate as f, isElement as g, isEmpty as p, isNumber as x, isObject as d, isUndefined as l } from "./utils/is.js";
3
+ import { treeFlat as S } from "./utils/tree.js";
4
+ import { thousandSeparator as k } from "./utils/number.js";
5
+ import { clearStorage as A, getStorage as C, getToken as B, removeStorage as I, removeToken as T, setStorage as b, setToken as v } from "./utils/storage.js";
6
+ import { confirmBox as E, confirmBoxAsync as O, messageAlert as h, notification as j } from "./utils/ui.js";
7
+ import { deepAssign as N, deepClone as P } from "./utils/object.js";
8
+ import { getParentByClass as U } from "./utils/dom.js";
9
+ import { default as w } from "./directives/click-outside.js";
10
+ export {
11
+ w as ClickOutside,
12
+ A as clearStorage,
13
+ E as confirmBox,
14
+ O as confirmBoxAsync,
15
+ N as deepAssign,
16
+ P as deepClone,
17
+ t as generateId,
18
+ o as generateString,
19
+ U as getParentByClass,
20
+ n as getRandomInt,
21
+ C as getStorage,
22
+ B as getToken,
23
+ a as guiID,
24
+ s as isArray,
25
+ m as isClient,
26
+ f as isDate,
27
+ g as isElement,
28
+ p as isEmpty,
29
+ x as isNumber,
30
+ d as isObject,
31
+ l as isUndefined,
32
+ h as messageAlert,
33
+ j as notification,
34
+ I as removeStorage,
35
+ T as removeToken,
36
+ b as setStorage,
37
+ v as setToken,
38
+ k as thousandSeparator,
39
+ S as treeFlat
40
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 根据类名获取父元素
3
+ * @param dom dom元素
4
+ * @param className css类名
5
+ * @return dom | null
6
+ */
7
+ export declare function getParentByClass(dom: any, className: string): any;
@@ -0,0 +1,6 @@
1
+ function r(t, n) {
2
+ return !t || t.tagName === "BODY" ? null : t.classList.contains(n) ? t : r(t.parentNode, n);
3
+ }
4
+ export {
5
+ r as getParentByClass
6
+ };
@@ -0,0 +1,8 @@
1
+ export * from './random';
2
+ export * from './is';
3
+ export * from './tree';
4
+ export * from './number';
5
+ export * from './storage';
6
+ export * from './ui';
7
+ export * from './object';
8
+ export * from './dom';
@@ -0,0 +1,42 @@
1
+ /**
2
+ * 判断是否为undefined
3
+ * @param val
4
+ * @returns
5
+ */
6
+ export declare function isUndefined(val: any): boolean;
7
+ /**
8
+ * 是否为数组
9
+ * @param val
10
+ * @returns
11
+ */
12
+ export declare function isArray(val: any): boolean;
13
+ /**
14
+ * 是否为对象
15
+ * @param val
16
+ * @returns
17
+ */
18
+ export declare function isObject(val: any): boolean;
19
+ /**
20
+ * 是否为日期时间
21
+ * @param val
22
+ * @returns
23
+ */
24
+ export declare function isDate(val: any): boolean;
25
+ /**
26
+ * 是否为空
27
+ * @param val
28
+ * @returns
29
+ */
30
+ export declare function isEmpty(val: unknown): boolean;
31
+ /**
32
+ * 判断对象是否为DOM元素
33
+ * @param e
34
+ * @returns
35
+ */
36
+ export declare function isElement(e: unknown): e is Element;
37
+ /**
38
+ * 是否是客户端
39
+ */
40
+ export declare const isClient: boolean;
41
+ /**是否未数值 */
42
+ export declare const isNumber: (val: any) => boolean;
@@ -0,0 +1,29 @@
1
+ function o(t) {
2
+ return t === void 0;
3
+ }
4
+ function e(t) {
5
+ return Object.prototype.toString.call(t) === "[object Array]";
6
+ }
7
+ function n(t) {
8
+ return typeof t == "object" && Object.prototype.toString.call(t) === "[object Object]";
9
+ }
10
+ function r(t) {
11
+ return Object.prototype.toString.call(t) === "[object Date]";
12
+ }
13
+ function i(t) {
14
+ return !t && t !== 0 || e(t) && t.length === 0 || n(t) && !Object.keys(t).length;
15
+ }
16
+ function c(t) {
17
+ return typeof Element > "u" ? !1 : t instanceof Element;
18
+ }
19
+ const u = typeof window < "u", f = (t) => typeof t == "number";
20
+ export {
21
+ e as isArray,
22
+ u as isClient,
23
+ r as isDate,
24
+ c as isElement,
25
+ i as isEmpty,
26
+ f as isNumber,
27
+ n as isObject,
28
+ o as isUndefined
29
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * 数字转成千分位
3
+ * @param num
4
+ * @returns
5
+ */
6
+ export declare function thousandSeparator(num: number | any): string;
@@ -0,0 +1,6 @@
1
+ function t(r) {
2
+ return r ? Object.prototype.toString.call(1) !== "[object Number]" ? `${r}` : `${r}`.replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, "$1,") : "0";
3
+ }
4
+ export {
5
+ t as thousandSeparator
6
+ };
@@ -0,0 +1,5 @@
1
+ export declare function deepClone(obj: any): any;
2
+ /**
3
+ *深度合并多个对象的方法
4
+ */
5
+ export declare function deepAssign(...arg: any[]): Record<string, any>;
@@ -0,0 +1,39 @@
1
+ import { isObject as c } from "./is.js";
2
+ function f(e) {
3
+ const o = Object.prototype.toString;
4
+ if (!e || typeof e != "object")
5
+ return e;
6
+ if (e.nodeType && "cloneNode" in e)
7
+ return e.cloneNode(!0);
8
+ if (o.call(e) === "[object Date]")
9
+ return new Date(e.getTime());
10
+ if (o.call(e) === "[object RegExp]") {
11
+ const t = [];
12
+ return e.global && t.push("g"), e.multiline && t.push("m"), e.ignoreCase && t.push("i"), new RegExp(e.source, t.join(""));
13
+ }
14
+ if (o.call(e) === "[object FormData]") {
15
+ const t = new FormData();
16
+ for (const [i, r] of e.entries())
17
+ t.append(i, r);
18
+ return t;
19
+ }
20
+ const n = Array.isArray(e) ? [] : e.constructor ? new e.constructor() : {};
21
+ for (const t in e)
22
+ n[t] = f(e[t]);
23
+ return n;
24
+ }
25
+ function l(...e) {
26
+ let o = e.length, n = e[0];
27
+ c(n) || (n = {});
28
+ for (let t = 1; t < o; t++) {
29
+ let i = e[t];
30
+ if (c(i))
31
+ for (let r in i)
32
+ r === "__proto__" || n === i[r] || (c(i[r]) ? n[r] = l(n[r], i[r]) : n[r] = i[r]);
33
+ }
34
+ return n;
35
+ }
36
+ export {
37
+ l as deepAssign,
38
+ f as deepClone
39
+ };
@@ -0,0 +1,25 @@
1
+ /**
2
+ * ==============================================
3
+ * 随机数
4
+ * ==============================================
5
+ */
6
+ /**
7
+ * 生成[0-10000]的随机数,针对数据小量使用
8
+ * @returns 随机数
9
+ */
10
+ export declare function generateId(): number;
11
+ /**
12
+ * 生成[0-max]的随机数
13
+ * @returns 随机数
14
+ */
15
+ export declare function getRandomInt(max: number): number;
16
+ /**
17
+ * 生成GUID
18
+ * @returns
19
+ */
20
+ export declare function guiID(): string;
21
+ /**
22
+ * 随机字符串
23
+ * @returns
24
+ */
25
+ export declare function generateString(): string;
@@ -0,0 +1,19 @@
1
+ function r() {
2
+ return Math.floor(Math.random() * 1e4);
3
+ }
4
+ function o(t) {
5
+ return Math.floor(Math.random() * Math.floor(t));
6
+ }
7
+ function a() {
8
+ const t = n;
9
+ return `${t()}${t()}-${t()}-${t()}-${t()}-${t()}${t()}${t()}`;
10
+ }
11
+ function n() {
12
+ return Math.floor((1 + Math.random()) * 65536).toString(16).substring(1);
13
+ }
14
+ export {
15
+ r as generateId,
16
+ n as generateString,
17
+ o as getRandomInt,
18
+ a as guiID
19
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * 获取用户token,包含过期时间判断
3
+ */
4
+ export declare function getToken(): any | null;
5
+ /**
6
+ * 设置用户token,有效期默认七天
7
+ * @param {*} value
8
+ */
9
+ export declare function setToken(value: any, expires?: number): void;
10
+ /**
11
+ * 移除token
12
+ */
13
+ export declare function removeToken(): void;
14
+ /**
15
+ * 设置缓存
16
+ * @param key key
17
+ * @param value 值
18
+ */
19
+ export declare function setStorage(key: string, value: any, tpye?: "local" | "session"): void;
20
+ /**
21
+ * 获取缓存
22
+ * @param key
23
+ * @returns
24
+ */
25
+ export declare function getStorage(key: string, tpye?: "local" | "session"): any;
26
+ /**
27
+ * 删除指定key的缓存
28
+ * @param key
29
+ */
30
+ export declare function removeStorage(key: string, tpye?: "local" | "session"): void;
31
+ /**
32
+ * 清除所有缓存
33
+ * @param tpye
34
+ */
35
+ export declare function clearStorage(tpye?: "local" | "session"): void;
@@ -0,0 +1,43 @@
1
+ function n() {
2
+ const o = localStorage.getItem("token");
3
+ if (!o)
4
+ return;
5
+ const e = JSON.parse(o);
6
+ if (e !== null)
7
+ if (e.expirse != null && e.expirse < (/* @__PURE__ */ new Date()).getTime())
8
+ localStorage.removeItem("token");
9
+ else
10
+ return e.value;
11
+ return null;
12
+ }
13
+ function r(o, e) {
14
+ !e && (e = 7 * 24 * 60 * 60 * 1e3) || (e = e * 1e3);
15
+ const t = { value: o, expirse: (/* @__PURE__ */ new Date()).getTime() + e };
16
+ localStorage.setItem("token", JSON.stringify(t));
17
+ }
18
+ function l() {
19
+ localStorage.removeItem("token");
20
+ }
21
+ function s(o, e, t = "local") {
22
+ const a = t == "local" ? localStorage : sessionStorage;
23
+ e != null && a.setItem(o, JSON.stringify(e));
24
+ }
25
+ function c(o, e = "local") {
26
+ let a = (e == "local" ? localStorage : sessionStorage).getItem(o);
27
+ return a && JSON.parse(a || "");
28
+ }
29
+ function g(o, e = "local") {
30
+ (e == "local" ? localStorage : sessionStorage).removeItem(o);
31
+ }
32
+ function i(o = "local") {
33
+ (o == "local" ? localStorage : sessionStorage).clear();
34
+ }
35
+ export {
36
+ i as clearStorage,
37
+ c as getStorage,
38
+ n as getToken,
39
+ g as removeStorage,
40
+ l as removeToken,
41
+ s as setStorage,
42
+ r as setToken
43
+ };
@@ -0,0 +1,7 @@
1
+ /**
2
+ * 树形数据扁平化处理
3
+ * @param data 数据
4
+ * @param key key属性
5
+ * @param children children属性
6
+ */
7
+ export declare function treeFlat(listData: any[], key?: string, children?: string): Record<string, any>;
@@ -0,0 +1,16 @@
1
+ function m(s, o = "key", h = "children") {
2
+ const t = {}, c = (r, f) => {
3
+ for (let n = 0; n < r.length; n++) {
4
+ const e = r[n], i = e[o];
5
+ if (!t[i]) {
6
+ t[i] = e, f && (t[i].parent = t[f]);
7
+ const l = e[h];
8
+ l && l.length > 0 && c(l, e[o]);
9
+ }
10
+ }
11
+ };
12
+ return c(s), t;
13
+ }
14
+ export {
15
+ m as treeFlat
16
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * 确认提示框
3
+ * @param str 提示信息
4
+ * @param callback 确认回调函数
5
+ * @param options MessageBox配置项,参考element-plus文档
6
+ */
7
+ export declare function confirmBox(str: string, callback: () => any | void, options?: any): void;
8
+ /**
9
+ * 同步的确认提示框
10
+ * @param str 提示信息
11
+ * @param callback 确认回调函数
12
+ * @param options MessageBox配置项,参考element-plus文档
13
+ * @returns
14
+ */
15
+ export declare function confirmBoxAsync(str: string, callback: () => any | void, options?: any): Promise<any>;
16
+ /**
17
+ * 消息提示
18
+ * @export
19
+ * @param type 类型
20
+ * @param message 消息
21
+ * @param html 是否为html
22
+ * @param duration 消失时间
23
+ */
24
+ export declare function messageAlert(type: "success" | "warning" | "error", message?: string, html?: boolean, duration?: number): void;
25
+ /**
26
+ * 侧窗提示
27
+ * @param type
28
+ * @param message
29
+ * @param html
30
+ * @param duration
31
+ */
32
+ export declare function notification(type: "success" | "warning" | "error" | "info", message?: string, html?: boolean, position?: "top-right" | "top-left" | "bottom-right" | "bottom-left", duration?: number): void;
@@ -0,0 +1,57 @@
1
+ import { ElMessageBox as f, ElMessage as m, ElNotification as l } from "element-plus";
2
+ function g(o, e, t) {
3
+ const n = {
4
+ beforeClose: (i, r, s) => {
5
+ i === "confirm" ? setTimeout(() => {
6
+ s();
7
+ }, 0) : s();
8
+ },
9
+ ...t
10
+ };
11
+ f.confirm(`此操作将${o}, 是否继续?`, "提示", n).then(async () => {
12
+ e && e();
13
+ }).catch(() => {
14
+ });
15
+ }
16
+ function h(o, e, t) {
17
+ return new Promise((n, i) => {
18
+ const r = {
19
+ beforeClose: (s, u, c) => {
20
+ s === "confirm" ? setTimeout(() => {
21
+ c();
22
+ }, 0) : c();
23
+ },
24
+ ...t
25
+ };
26
+ f.confirm(`${o}`, "Tip", r).then(() => {
27
+ n(e && e());
28
+ }).catch(() => {
29
+ });
30
+ });
31
+ }
32
+ function p(o, e = "", t = !1, n = 3e3) {
33
+ m({
34
+ showClose: !0,
35
+ message: e,
36
+ type: o,
37
+ duration: n,
38
+ dangerouslyUseHTMLString: t
39
+ });
40
+ }
41
+ function T(o, e = "", t = !1, n = "bottom-right", i = 0) {
42
+ l({
43
+ title: "消息通知",
44
+ message: e,
45
+ type: o,
46
+ dangerouslyUseHTMLString: t,
47
+ duration: i,
48
+ showClose: !0,
49
+ position: n
50
+ });
51
+ }
52
+ export {
53
+ g as confirmBox,
54
+ h as confirmBoxAsync,
55
+ p as messageAlert,
56
+ T as notification
57
+ };
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@qy_better_lib/core",
3
+ "private": false,
4
+ "version": "0.0.1",
5
+ "description": "qy better lib core",
6
+ "author": "luhuiming",
7
+ "license": "ISC",
8
+ "scripts": {
9
+ "build:lib": "vite build --config vite.lib.config.ts",
10
+ "build:dist-min": "vite build --config vite.dist.min.config.ts",
11
+ "build": "yarn build:lib && yarn build:dist-min"
12
+ },
13
+ "main": "lib/index.js",
14
+ "module": "lib/index.js",
15
+ "types": "lib/index.d.ts",
16
+ "typesVersions": {
17
+ "*": {
18
+ "lib/index.js": [
19
+ "lib/index.d.ts"
20
+ ],
21
+ "@qy-better-lib/core": [
22
+ "lib/index.d.ts"
23
+ ],
24
+ "*": [
25
+ "*",
26
+ "dist/*",
27
+ "lib/*",
28
+ "lib/*.d.ts",
29
+ "lib/*/index.d.ts"
30
+ ]
31
+ }
32
+ },
33
+ "exports": {
34
+ ".": {
35
+ "import": "./lib/index.js"
36
+ },
37
+ "./directives": "./lib/directives/index.js",
38
+ "./directives/*": "./lib/directives/*/*.js",
39
+ "./utils": "./lib/utils/index.js",
40
+ "./utils/*": "./lib/utils/*.js"
41
+ },
42
+ "publishConfig": {
43
+ "access": "public",
44
+ "registry": "https://registry.npmjs.org/"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.14.9",
48
+ "@vitejs/plugin-vue": "^5.0.5",
49
+ "element-plus": "^2.7.6",
50
+ "vite": "^5.3.2",
51
+ "vite-plugin-dts": "^3.9.1",
52
+ "vue": "^3.4.31"
53
+ }
54
+ }
@@ -0,0 +1,115 @@
1
+ import { isElement, isClient } from "./../utils";
2
+ import type {
3
+ ComponentPublicInstance,
4
+ DirectiveBinding,
5
+ ObjectDirective,
6
+ } from "vue";
7
+
8
+ type DocumentHandler = <T extends MouseEvent>(mouseup: T, mousedown: T) => void;
9
+
10
+ type FlushList = Map<
11
+ HTMLElement,
12
+ {
13
+ documentHandler: DocumentHandler;
14
+ bindingFn: (...args: unknown[]) => unknown;
15
+ }[]
16
+ >;
17
+
18
+ const nodeList: FlushList = new Map();
19
+
20
+ let startClick: MouseEvent;
21
+
22
+ if (isClient) {
23
+ document.addEventListener("mousedown", (e: MouseEvent) => (startClick = e));
24
+ document.addEventListener("mouseup", (e: MouseEvent) => {
25
+ for (const handlers of nodeList.values()) {
26
+ for (const { documentHandler } of handlers) {
27
+ documentHandler(e as MouseEvent, startClick);
28
+ }
29
+ }
30
+ });
31
+ }
32
+
33
+ function createDocumentHandler(
34
+ el: HTMLElement,
35
+ binding: DirectiveBinding
36
+ ): DocumentHandler {
37
+ let excludes: HTMLElement[] = [];
38
+ if (Array.isArray(binding.arg)) {
39
+ excludes = binding.arg;
40
+ } else if (isElement(binding.arg)) {
41
+ excludes.push(binding.arg as unknown as HTMLElement);
42
+ }
43
+ return function (mouseup, mousedown) {
44
+ const popperRef = (
45
+ binding.instance as ComponentPublicInstance<{
46
+ popperRef: HTMLElement | null;
47
+ }>
48
+ ).popperRef;
49
+ const mouseUpTarget = mouseup.target as Node;
50
+ const mouseDownTarget = mousedown?.target as Node;
51
+ const isBound = !binding || !binding.instance;
52
+ const isTargetExists = !mouseUpTarget || !mouseDownTarget;
53
+ const isContainedByEl =
54
+ el.contains(mouseUpTarget) || el.contains(mouseDownTarget);
55
+ const isSelf = el === mouseUpTarget;
56
+
57
+ const isTargetExcluded =
58
+ (excludes.length &&
59
+ excludes.some((item) => item?.contains(mouseUpTarget))) ||
60
+ (excludes.length && excludes.includes(mouseDownTarget as HTMLElement));
61
+ const isContainedByPopper =
62
+ popperRef &&
63
+ (popperRef.contains(mouseUpTarget) ||
64
+ popperRef.contains(mouseDownTarget));
65
+ if (
66
+ isBound ||
67
+ isTargetExists ||
68
+ isContainedByEl ||
69
+ isSelf ||
70
+ isTargetExcluded ||
71
+ isContainedByPopper
72
+ ) {
73
+ return;
74
+ }
75
+ binding.value(mouseup, mousedown);
76
+ };
77
+ }
78
+
79
+ const ClickOutside: ObjectDirective = {
80
+ beforeMount(el: HTMLElement, binding: DirectiveBinding) {
81
+ if (!nodeList.has(el)) {
82
+ nodeList.set(el, []);
83
+ }
84
+
85
+ nodeList.get(el)?.push({
86
+ documentHandler: createDocumentHandler(el, binding),
87
+ bindingFn: binding.value,
88
+ });
89
+ },
90
+ updated(el: HTMLElement, binding: DirectiveBinding) {
91
+ if (!nodeList.has(el)) {
92
+ nodeList.set(el, []);
93
+ }
94
+
95
+ const handlers = nodeList.get(el);
96
+ const oldHandlerIndex = handlers?.findIndex(
97
+ (item) => item.bindingFn === binding.oldValue
98
+ );
99
+ const newHandler = {
100
+ documentHandler: createDocumentHandler(el, binding),
101
+ bindingFn: binding.value,
102
+ };
103
+
104
+ if (oldHandlerIndex && oldHandlerIndex >= 0) {
105
+ handlers?.splice(oldHandlerIndex, 1, newHandler);
106
+ } else {
107
+ handlers?.push(newHandler);
108
+ }
109
+ },
110
+ unmounted(el: HTMLElement) {
111
+ nodeList.delete(el);
112
+ },
113
+ };
114
+
115
+ export default ClickOutside;
@@ -0,0 +1,3 @@
1
+ import ClickOutside from "./click-outside";
2
+
3
+ export { ClickOutside };
package/src/index.ts ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./utils/index";
2
+ export * from "./directives/index";
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 根据类名获取父元素
3
+ * @param dom dom元素
4
+ * @param className css类名
5
+ * @return dom | null
6
+ */
7
+ export function getParentByClass(dom: any, className: string): any {
8
+ if (!dom || dom.tagName === "BODY") {
9
+ return null;
10
+ }
11
+ if (dom.classList.contains(className)) {
12
+ return dom;
13
+ }
14
+ return getParentByClass(dom.parentNode, className);
15
+ }
@@ -0,0 +1,8 @@
1
+ export * from "./random";
2
+ export * from "./is";
3
+ export * from "./tree";
4
+ export * from "./number";
5
+ export * from "./storage";
6
+ export * from "./ui";
7
+ export * from "./object";
8
+ export * from "./dom";
@@ -0,0 +1,67 @@
1
+ /**
2
+ * 判断是否为undefined
3
+ * @param val
4
+ * @returns
5
+ */
6
+ export function isUndefined(val: any): boolean {
7
+ return val === undefined;
8
+ }
9
+ /**
10
+ * 是否为数组
11
+ * @param val
12
+ * @returns
13
+ */
14
+ export function isArray(val: any) {
15
+ return Object.prototype.toString.call(val) === "[object Array]";
16
+ }
17
+ /**
18
+ * 是否为对象
19
+ * @param val
20
+ * @returns
21
+ */
22
+ export function isObject(val: any) {
23
+ return (
24
+ typeof val === "object" &&
25
+ Object.prototype.toString.call(val) === "[object Object]"
26
+ );
27
+ }
28
+
29
+ /**
30
+ * 是否为日期时间
31
+ * @param val
32
+ * @returns
33
+ */
34
+ export function isDate(val: any) {
35
+ return Object.prototype.toString.call(val) === "[object Date]";
36
+ }
37
+
38
+ /**
39
+ * 是否为空
40
+ * @param val
41
+ * @returns
42
+ */
43
+ export function isEmpty(val: unknown) {
44
+ return (
45
+ (!val && val !== 0) ||
46
+ (isArray(val) && (<Array<unknown>>val).length === 0) ||
47
+ (isObject(val) && !Object.keys(val as any).length)
48
+ );
49
+ }
50
+
51
+ /**
52
+ * 判断对象是否为DOM元素
53
+ * @param e
54
+ * @returns
55
+ */
56
+ export function isElement(e: unknown): e is Element {
57
+ if (typeof Element === "undefined") return false;
58
+ return e instanceof Element;
59
+ }
60
+
61
+ /**
62
+ * 是否是客户端
63
+ */
64
+ export const isClient = typeof window !== "undefined";
65
+
66
+ /**是否未数值 */
67
+ export const isNumber = (val: any) => typeof val === "number";
@@ -0,0 +1,14 @@
1
+ /**
2
+ * 数字转成千分位
3
+ * @param num
4
+ * @returns
5
+ */
6
+ export function thousandSeparator(num: number | any): string {
7
+ if (!num) {
8
+ return "0";
9
+ }
10
+ if (Object.prototype.toString.call(1) !== "[object Number]") {
11
+ return `${num}`;
12
+ }
13
+ return `${num}`.replace(/(\d{1,3})(?=(\d{3})+(?:$|\.))/g, "$1,");
14
+ }
@@ -0,0 +1,76 @@
1
+ import { isObject } from "./is";
2
+
3
+ // 深拷贝对象
4
+ export function deepClone(obj: any): any {
5
+ const _toString: Function = Object.prototype.toString;
6
+ // null, undefined, non-object, function
7
+ if (!obj || typeof obj !== "object") {
8
+ return obj;
9
+ }
10
+ // DOM Node
11
+ if (obj.nodeType && "cloneNode" in obj) {
12
+ return obj.cloneNode(true);
13
+ }
14
+ // Date
15
+ if (_toString.call(obj) === "[object Date]") {
16
+ return new Date(obj.getTime());
17
+ }
18
+ // RegExp
19
+ if (_toString.call(obj) === "[object RegExp]") {
20
+ const flags: Array<string> = [];
21
+ if (obj.global) {
22
+ flags.push("g");
23
+ }
24
+ if (obj.multiline) {
25
+ flags.push("m");
26
+ }
27
+ if (obj.ignoreCase) {
28
+ flags.push("i");
29
+ }
30
+ return new RegExp(obj.source, flags.join(""));
31
+ }
32
+ if (_toString.call(obj) === "[object FormData]") {
33
+ const formData = new FormData();
34
+ for (const [key, value] of obj.entries()) {
35
+ formData.append(key, value);
36
+ }
37
+ return formData;
38
+ }
39
+ const result: any = Array.isArray(obj)
40
+ ? []
41
+ : obj.constructor
42
+ ? new obj.constructor()
43
+ : {};
44
+
45
+ for (const key in obj) {
46
+ result[key] = deepClone(obj[key]);
47
+ }
48
+ return result;
49
+ }
50
+
51
+ /**
52
+ *深度合并多个对象的方法
53
+ */
54
+ export function deepAssign(...arg: any[]) {
55
+ let len: number = arg.length,
56
+ target: Record<string, any> = arg[0];
57
+ if (!isObject(target)) {
58
+ target = {};
59
+ }
60
+ for (let i = 1; i < len; i++) {
61
+ let source = arg[i];
62
+ if (isObject(source)) {
63
+ for (let s in source) {
64
+ if (s === "__proto__" || target === source[s]) {
65
+ continue;
66
+ }
67
+ if (isObject(source[s])) {
68
+ target[s] = deepAssign(target[s], source[s]);
69
+ } else {
70
+ target[s] = source[s];
71
+ }
72
+ }
73
+ }
74
+ }
75
+ return target;
76
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * ==============================================
3
+ * 随机数
4
+ * ==============================================
5
+ */
6
+
7
+ /**
8
+ * 生成[0-10000]的随机数,针对数据小量使用
9
+ * @returns 随机数
10
+ */
11
+ export function generateId(): number {
12
+ return Math.floor(Math.random() * 10000);
13
+ }
14
+
15
+ /**
16
+ * 生成[0-max]的随机数
17
+ * @returns 随机数
18
+ */
19
+ export function getRandomInt(max: number) {
20
+ return Math.floor(Math.random() * Math.floor(max));
21
+ }
22
+
23
+ /**
24
+ * 生成GUID
25
+ * @returns
26
+ */
27
+ export function guiID() {
28
+ const gs = generateString;
29
+ return `${gs()}${gs()}-${gs()}-${gs()}-${gs()}-${gs()}${gs()}${gs()}`;
30
+ }
31
+
32
+ /**
33
+ * 随机字符串
34
+ * @returns
35
+ */
36
+ export function generateString(): string {
37
+ return Math.floor((1 + Math.random()) * 0x10000)
38
+ .toString(16)
39
+ .substring(1);
40
+ }
@@ -0,0 +1,86 @@
1
+ /**
2
+ * 获取用户token,包含过期时间判断
3
+ */
4
+ export function getToken(): any | null {
5
+ const session = localStorage.getItem("token");
6
+ if (!session) {
7
+ return undefined;
8
+ }
9
+ const data = JSON.parse(session);
10
+ if (data !== null) {
11
+ if (data.expirse != null && data.expirse < new Date().getTime()) {
12
+ localStorage.removeItem("token");
13
+ } else {
14
+ return data.value;
15
+ }
16
+ }
17
+ return null;
18
+ }
19
+
20
+ /**
21
+ * 设置用户token,有效期默认七天
22
+ * @param {*} value
23
+ */
24
+ export function setToken(value: any, expires?: number): void {
25
+ (!expires && (expires = 7 * 24 * 60 * 60 * 1000)) ||
26
+ (expires = expires * 1000);
27
+ const data = { value: value, expirse: new Date().getTime() + expires };
28
+ localStorage.setItem("token", JSON.stringify(data));
29
+ }
30
+
31
+ /**
32
+ * 移除token
33
+ */
34
+ export function removeToken(): void {
35
+ localStorage.removeItem("token");
36
+ }
37
+ /**
38
+ * 设置缓存
39
+ * @param key key
40
+ * @param value 值
41
+ */
42
+ export function setStorage(
43
+ key: string,
44
+ value: any,
45
+ tpye: "local" | "session" = "local"
46
+ ): void {
47
+ const storage = tpye == "local" ? localStorage : sessionStorage;
48
+ value != undefined && storage.setItem(key, JSON.stringify(value));
49
+ }
50
+ /**
51
+ * 获取缓存
52
+ * @param key
53
+ * @returns
54
+ */
55
+ export function getStorage(
56
+ key: string,
57
+ tpye: "local" | "session" = "local"
58
+ ): any {
59
+ const storage = tpye == "local" ? localStorage : sessionStorage;
60
+ let session = storage.getItem(key);
61
+ if (session) {
62
+ return JSON.parse(session || "");
63
+ }
64
+ return session;
65
+ }
66
+
67
+ /**
68
+ * 删除指定key的缓存
69
+ * @param key
70
+ */
71
+ export function removeStorage(
72
+ key: string,
73
+ tpye: "local" | "session" = "local"
74
+ ): void {
75
+ const storage = tpye == "local" ? localStorage : sessionStorage;
76
+ storage.removeItem(key);
77
+ }
78
+
79
+ /**
80
+ * 清除所有缓存
81
+ * @param tpye
82
+ */
83
+ export function clearStorage(tpye: "local" | "session" = "local") {
84
+ const storage = tpye == "local" ? localStorage : sessionStorage;
85
+ storage.clear();
86
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * 树形数据扁平化处理
3
+ * @param data 数据
4
+ * @param key key属性
5
+ * @param children children属性
6
+ */
7
+ export function treeFlat(
8
+ listData: any[],
9
+ key: string = "key",
10
+ children: string = "children"
11
+ ): Record<string, any> {
12
+ const map: Record<string, any> = {};
13
+ const flat = (data: any[], parentKey?: string) => {
14
+ for (let i = 0; i < data.length; i++) {
15
+ const item = data[i];
16
+ const mapKey = item[key];
17
+ if (map[mapKey]) {
18
+ } else {
19
+ map[mapKey] = item;
20
+ if (parentKey) map[mapKey].parent = map[parentKey];
21
+ const itemChildren = item[children];
22
+ if (itemChildren && itemChildren.length > 0) {
23
+ flat(itemChildren, item[key]);
24
+ }
25
+ }
26
+ }
27
+ };
28
+ flat(listData);
29
+ return map;
30
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * ==============================================
3
+ * 强依赖element-plus
4
+ * ==============================================
5
+ */
6
+ import { ElMessage, ElMessageBox, ElNotification } from "element-plus";
7
+
8
+ /**
9
+ * 确认提示框
10
+ * @param str 提示信息
11
+ * @param callback 确认回调函数
12
+ * @param options MessageBox配置项,参考element-plus文档
13
+ */
14
+ export function confirmBox(
15
+ str: string,
16
+ callback: () => any | void,
17
+ options?: any
18
+ ) {
19
+ const option = {
20
+ beforeClose: (
21
+ action: "confirm" | "cancel" | "close",
22
+ instance: any,
23
+ done: () => void
24
+ ) => {
25
+ if (action === "confirm") {
26
+ setTimeout(() => {
27
+ done();
28
+ }, 0);
29
+ } else {
30
+ done();
31
+ }
32
+ },
33
+ ...options,
34
+ };
35
+ ElMessageBox.confirm(`此操作将${str}, 是否继续?`, "提示", option)
36
+ .then(async () => {
37
+ callback && callback();
38
+ })
39
+ .catch(() => {});
40
+ }
41
+
42
+ /**
43
+ * 同步的确认提示框
44
+ * @param str 提示信息
45
+ * @param callback 确认回调函数
46
+ * @param options MessageBox配置项,参考element-plus文档
47
+ * @returns
48
+ */
49
+ export function confirmBoxAsync(
50
+ str: string,
51
+ callback: () => any | void,
52
+ options?: any
53
+ ): Promise<any> {
54
+ return new Promise((resolve, reject) => {
55
+ const option = {
56
+ beforeClose: (
57
+ action: "confirm" | "cancel" | "close",
58
+ instance: any,
59
+ done: () => void
60
+ ) => {
61
+ if (action === "confirm") {
62
+ setTimeout(() => {
63
+ done();
64
+ }, 0);
65
+ } else {
66
+ done();
67
+ }
68
+ },
69
+ ...options,
70
+ };
71
+ ElMessageBox.confirm(`${str}`, "Tip", option)
72
+ .then(() => {
73
+ resolve(callback && callback());
74
+ })
75
+ .catch(() => {});
76
+ });
77
+ }
78
+
79
+ /**
80
+ * 消息提示
81
+ * @export
82
+ * @param type 类型
83
+ * @param message 消息
84
+ * @param html 是否为html
85
+ * @param duration 消失时间
86
+ */
87
+ export function messageAlert(
88
+ type: "success" | "warning" | "error",
89
+ message: string = "",
90
+ html: boolean = false,
91
+ duration: number = 3000
92
+ ) {
93
+ ElMessage({
94
+ showClose: true,
95
+ message: message,
96
+ type: type,
97
+ duration,
98
+ dangerouslyUseHTMLString: html,
99
+ });
100
+ }
101
+
102
+ /**
103
+ * 侧窗提示
104
+ * @param type
105
+ * @param message
106
+ * @param html
107
+ * @param duration
108
+ */
109
+ export function notification(
110
+ type: "success" | "warning" | "error" | "info",
111
+ message: string = "",
112
+ html: boolean = false,
113
+ position:
114
+ | "top-right"
115
+ | "top-left"
116
+ | "bottom-right"
117
+ | "bottom-left" = "bottom-right",
118
+ duration: number = 0
119
+ ) {
120
+ ElNotification({
121
+ title: "消息通知",
122
+ message,
123
+ type,
124
+ dangerouslyUseHTMLString: html,
125
+ duration,
126
+ showClose: true,
127
+ position,
128
+ });
129
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "compilerOptions": {},
3
+ "extends": "../../tsconfig.json",
4
+ "include": ["./src/**/*.ts"]
5
+ }
@@ -0,0 +1 @@
1
+ declare type $TODO = any
@@ -0,0 +1,4 @@
1
+ declare module "*.json" {
2
+ const value: any;
3
+ export default value;
4
+ }
@@ -0,0 +1,5 @@
1
+ declare module '*.vue' {
2
+ import { ComponentOptions } from 'vue'
3
+ const Component: ComponentOptions
4
+ export default Component
5
+ }