pen-it 1.0.0 → 1.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.
- package/README.md +74 -128
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,122 +22,106 @@ import { isArray, formatFull, deepClone, unique } from 'pen-it'
|
|
|
22
22
|
|
|
23
23
|
### 类型判断 — `is`
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
| `isElement(val)` | 判断是否为 DOM 元素 | `isElement(document.body) // true` |
|
|
53
|
-
| `isIOS()` | 判断设备是否为 iOS | `isIOS() // true` |
|
|
25
|
+
- **`isArray(value)`** — 判断是否为数组。 `isArray([1,2,3]) // true`
|
|
26
|
+
- **`isObject(value)`** — 判断是否为对象(不含数组)。 `isObject({a:1}) // true`
|
|
27
|
+
- **`is(val, type)`** — 通用类型判断(内部工具)。 `is([], "Array") // true`
|
|
28
|
+
- **`isFunction(val)`** — 判断是否为函数。 `isFunction(()=>{}) // true`
|
|
29
|
+
- **`isAsyncFunction(val)`** — 判断是否为异步函数。 `isAsyncFunction(async ()=>{}) // true`
|
|
30
|
+
- **`isPromise(value)`** — 判断是否为 Promise。 `isPromise(Promise.resolve()) // true`
|
|
31
|
+
- **`isDate(val)`** — 判断是否为 Date 对象。 `isDate(new Date()) // true`
|
|
32
|
+
- **`isNumber(val)`** — 判断是否为数字(含 NaN/Infinity)。 `isNumber(42) // true`
|
|
33
|
+
- **`isInt(val)`** — 判断是否为整数。 `isInt(42) // true`
|
|
34
|
+
- **`isFloat(val)`** — 判断是否为浮点数。 `isFloat(3.14) // true`
|
|
35
|
+
- **`isString(val)`** — 判断是否为字符串。 `isString("hello") // true`
|
|
36
|
+
- **`isBoolean(val)`** — 判断是否为布尔值。 `isBoolean(true) // true`
|
|
37
|
+
- **`isSymbol(value)`** — 判断是否为 Symbol。 `isSymbol(Symbol("foo")) // true`
|
|
38
|
+
- **`isPrimitive(value)`** — 判断是否为原始类型。 `isPrimitive(42) // true`
|
|
39
|
+
- **`isNull(val)`** — 判断是否为 null。 `isNull(null) // true`
|
|
40
|
+
- **`isDef(val)`** — 判断是否不是 undefined。 `isDef("hello") // true`
|
|
41
|
+
- **`isUnDef(val)`** — 判断是否为 undefined。 `isUnDef(undefined) // true`
|
|
42
|
+
- **`isNullOrUnDef(val)`** — 判断是否为 null 或 undefined。 `isNullOrUnDef(null) // true`
|
|
43
|
+
- **`isEmpty(value)`** — 判断是否为空(完备版:支持 Date/Map/Set 等)。 `isEmpty("") // true`
|
|
44
|
+
- **`isEmptySv(value)`** — 判断是否为空(简化版)。 `isEmptySv([]) // true`
|
|
45
|
+
- **`isEqual(x, y)`** — 深度相等比较(支持 Date/RegExp)。 `isEqual({a:1}, {a:1}) // true`
|
|
46
|
+
- **`isHexColor(str)`** — 判断是否为十六进制颜色。 `isHexColor("#fff") // true`
|
|
47
|
+
- **`isValidEmail(email)`** — 判断是否为有效邮箱。 `isValidEmail("a@b.com") // true`
|
|
48
|
+
- **`isPC()`** — 判断是否为浏览器环境。 `isPC() // true`
|
|
49
|
+
- **`isWindow(val)`** — 判断是否为 window 对象。 `isWindow(window) // true`
|
|
50
|
+
- **`isElement(val)`** — 判断是否为 DOM 元素。 `isElement(document.body) // true`
|
|
51
|
+
- **`isIOS()`** — 判断设备是否为 iOS。 `isIOS() // true`
|
|
54
52
|
|
|
55
53
|
---
|
|
56
54
|
|
|
57
55
|
### 日期时间格式化 — `format`
|
|
58
56
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
| `formatYMD(date)` | 中文年月日 | `"2026年6月3日"` |
|
|
64
|
-
| `formatWeek(date)` | 星期几 | `"星期三"` |
|
|
57
|
+
- **`formatFull(date)`** — 完整日期时间(斜杠分隔)。 `formatFull(new Date()) // "2026/06/03 14:30:45"`
|
|
58
|
+
- **`formatFullReplace(date)`** — 完整日期时间(短横线分隔)。 `formatFullReplace(new Date()) // "2026-06-03 14:30:45"`
|
|
59
|
+
- **`formatYMD(date)`** — 中文年月日。 `formatYMD(new Date()) // "2026年6月3日"`
|
|
60
|
+
- **`formatWeek(date)`** — 星期几。 `formatWeek(new Date()) // "星期三"`
|
|
65
61
|
|
|
66
62
|
---
|
|
67
63
|
|
|
68
64
|
### 数字与货币格式化 — `format`
|
|
69
65
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
| `compactCN(value)` | 大数简化(中文缩写) | `compactCN(12345) // "1.2万"` |
|
|
77
|
-
| `signed(value, digit)` | 带正负号显示 | `signed(42, 1) // "+42.0"` |
|
|
66
|
+
- **`formatRmb(value, options)`** — 货币格式化(人民币)。 `formatRmb(1234.56, { type: "zh-CN", currency: "CNY" }) // "¥1,234.56"`
|
|
67
|
+
- **`formatNum(value)`** — 千位分隔符。 `formatNum(1234567) // "1,234,567"`
|
|
68
|
+
- **`percentCN(value, digit)`** — 百分比格式化。 `percentCN(0.1234, 2) // "12.34%"`
|
|
69
|
+
- **`compactEN(value)`** — 大数简化(英文缩写)。 `compactEN(12345) // "12K"`
|
|
70
|
+
- **`compactCN(value)`** — 大数简化(中文缩写)。 `compactCN(12345) // "1.2万"`
|
|
71
|
+
- **`signed(value, digit)`** — 带正负号显示。 `signed(42, 1) // "+42.0"`
|
|
78
72
|
|
|
79
73
|
---
|
|
80
74
|
|
|
81
75
|
### 字符串处理 — `format`
|
|
82
76
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
| `truncate(str, max, suffix?)` | 超长文本截断 | `truncate("Hello World", 8) // "Hello..."` |
|
|
96
|
-
| `truncateByWords(str, max, suffix?)` | 按字数截断(中文友好) | `truncateByWords("你好世界欢迎你", 4) // "你好世界..."` |
|
|
77
|
+
- **`maskPhone(phone)`** — 手机号脱敏(隐藏中间4位)。 `maskPhone("13812345678") // "138****5678"`
|
|
78
|
+
- **`spacePhone(phone)`** — 手机号空格分隔。 `spacePhone("13812345678") // "138 1234 5678"`
|
|
79
|
+
- **`capitalize(str)`** — 每个单词首字母大写。 `capitalize("hello world") // "Hello World"`
|
|
80
|
+
- **`kebabToCamel(str)`** — 短横线转小驼峰。 `kebabToCamel("hello-world") // "helloWorld"`
|
|
81
|
+
- **`camelToKebab(str)`** — 驼峰转短横线。 `camelToKebab("helloWorld") // "hello-world"`
|
|
82
|
+
- **`toCamel(str)`** — 下划线转驼峰。 `toCamel("hello_world") // "helloWorld"`
|
|
83
|
+
- **`firstUpper(str)`** — 首字母大写。 `firstUpper("hello") // "Hello"`
|
|
84
|
+
- **`firstLower(str)`** — 首字母小写。 `firstLower("Hello") // "hello"`
|
|
85
|
+
- **`reverse(str)`** — 反转字符串。 `reverse("hello") // "olleh"`
|
|
86
|
+
- **`trimAll(str)`** — 去除所有空格。 `trimAll(" h e l lo ") // "hello"`
|
|
87
|
+
- **`truncate(str, max, suffix?)`** — 超长文本截断。 `truncate("Hello World", 8) // "Hello..."`
|
|
88
|
+
- **`truncateByWords(str, max, suffix?)`** — 按字数截断(中文友好)。 `truncateByWords("你好世界欢迎你", 4) // "你好世界..."`
|
|
97
89
|
|
|
98
90
|
---
|
|
99
91
|
|
|
100
92
|
### 存储 — `storage`
|
|
101
93
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
| `localRm(key)` | 移除指定 localStorage | `localRm("user")` |
|
|
107
|
-
| `localClear()` | 清除所有 localStorage | `localClear()` |
|
|
94
|
+
- **`localGet<T>(key)`** — 获取 localStorage(自动 JSON 解析)。 `localGet("user") // { name: "张三" }`
|
|
95
|
+
- **`localSet(key, value)`** — 设置 localStorage(自动 JSON 序列化)。 `localSet("user", { name: "张三" })`
|
|
96
|
+
- **`localRm(key)`** — 移除指定 localStorage。 `localRm("user")`
|
|
97
|
+
- **`localClear()`** — 清除所有 localStorage。 `localClear()`
|
|
108
98
|
|
|
109
99
|
---
|
|
110
100
|
|
|
111
101
|
### 拷贝 — `copy`
|
|
112
102
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
| `deepCloneWithJSON(obj)` | JSON 深拷贝(仅 JSON 安全类型) | `deepCloneWithJSON({a:1})` |
|
|
117
|
-
| `shallowClone(obj)` | 浅拷贝(仅第一层) | `shallowClone({a:1, b:{c:2}})` |
|
|
103
|
+
- **`deepClone(obj)`** — 递归深拷贝(支持 Date/RegExp/Map/Set/循环引用)。 `deepClone({a:1, b:{c:2}})`
|
|
104
|
+
- **`deepCloneWithJSON(obj)`** — JSON 深拷贝(仅 JSON 安全类型)。 `deepCloneWithJSON({a:1})`
|
|
105
|
+
- **`shallowClone(obj)`** — 浅拷贝(仅第一层)。 `shallowClone({a:1, b:{c:2}})`
|
|
118
106
|
|
|
119
107
|
---
|
|
120
108
|
|
|
121
109
|
### 数组 — `array`
|
|
122
110
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
| `sortByKey(arr, key, order?)` | 按对象属性排序 | `sortByKey([{age:30},{age:20}], "age")` |
|
|
130
|
-
| `toArray(arrayLike)` | 类数组转数组 | `toArray(document.querySelectorAll("div"))` |
|
|
111
|
+
- **`unique(arr)`** — Set 去重。 `unique([1,2,2,3]) // [1,2,3]`
|
|
112
|
+
- **`uniqueByKey(arr, key)`** — 对象数组按 key 去重。 `uniqueByKey([{id:1},{id:1}], "id")`
|
|
113
|
+
- **`sortNumAsc(arr)`** — 数值升序。 `sortNumAsc([3,1,2]) // [1,2,3]`
|
|
114
|
+
- **`sortNumDesc(arr)`** — 数值降序。 `sortNumDesc([1,3,2]) // [3,2,1]`
|
|
115
|
+
- **`sortByKey(arr, key, order?)`** — 按对象属性排序。 `sortByKey([{age:30},{age:20}], "age")`
|
|
116
|
+
- **`toArray(arrayLike)`** — 类数组转数组。 `toArray(document.querySelectorAll("div"))`
|
|
131
117
|
|
|
132
118
|
---
|
|
133
119
|
|
|
134
120
|
### Cookie — `cookie`
|
|
135
121
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
| `getCookie(name)` | 获取 Cookie | `getCookie("token") // "abc123"` |
|
|
140
|
-
| `delCookie(name)` | 删除 Cookie | `delCookie("token")` |
|
|
122
|
+
- **`setCookie(name, value, days?)`** — 设置 Cookie(默认7天)。 `setCookie("token", "abc123", 30)`
|
|
123
|
+
- **`getCookie(name)`** — 获取 Cookie。 `getCookie("token") // "abc123"`
|
|
124
|
+
- **`delCookie(name)`** — 删除 Cookie。 `delCookie("token")`
|
|
141
125
|
|
|
142
126
|
---
|
|
143
127
|
|
|
@@ -145,56 +129,18 @@ import { isArray, formatFull, deepClone, unique } from 'pen-it'
|
|
|
145
129
|
|
|
146
130
|
#### URL 参数
|
|
147
131
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
| `getUrlParam(key, url?)` | 获取单个 URL 参数 | `getUrlParam("a") // "1"` |
|
|
152
|
-
| `toQueryString(params)` | 对象转 URL 参数字符串 | `toQueryString({a:1,b:"hello"}) // "a=1&b=hello"` |
|
|
132
|
+
- **`getUrlParams(url?)`** — 获取 URL 参数对象。 `getUrlParams("?a=1&b=2") // {a:"1",b:"2"}`
|
|
133
|
+
- **`getUrlParam(key, url?)`** — 获取单个 URL 参数。 `getUrlParam("a") // "1"`
|
|
134
|
+
- **`toQueryString(params)`** — 对象转 URL 参数字符串。 `toQueryString({a:1,b:"hello"}) // "a=1&b=hello"`
|
|
153
135
|
|
|
154
136
|
#### 剪贴板与文件
|
|
155
137
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
| `downloadFile(content, filename, mimeType?)` | 下载文件(Blob) | `downloadFile("Hello", "hello.txt")` |
|
|
160
|
-
| `exportJSON(data, filename?)` | 导出 JSON 为文件 | `exportJSON({name:"张三"})` |
|
|
138
|
+
- **`copyToClipboard(text)`** — 复制文本到剪贴板(支持降级)。 `await copyToClipboard("Hello")`
|
|
139
|
+
- **`downloadFile(content, filename, mimeType?)`** — 下载文件(Blob)。 `downloadFile("Hello", "hello.txt")`
|
|
140
|
+
- **`exportJSON(data, filename?)`** — 导出 JSON 为文件。 `exportJSON({name:"张三"})`
|
|
161
141
|
|
|
162
142
|
#### 页面滚动
|
|
163
143
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
| `scrollToBottom(behavior?)` | 滚动到底部(默认平滑) | `scrollToBottom()` |
|
|
168
|
-
| `onScroll(callback)` | 监听滚动(rAF 节流),返回清理函数 | `const off = onScroll(y => console.log(y))` |
|
|
169
|
-
|
|
170
|
-
---
|
|
171
|
-
|
|
172
|
-
## 项目结构
|
|
173
|
-
|
|
174
|
-
```
|
|
175
|
-
pen-it/
|
|
176
|
-
├── dist/ # 构建输出(CJS + ESM + .d.ts)
|
|
177
|
-
├── src/ # 源码
|
|
178
|
-
│ ├── index.ts # 统一导出入口
|
|
179
|
-
│ ├── is/ # 类型判断(28个函数)
|
|
180
|
-
│ ├── format/ # 日期/数字/字符串格式化(22个函数)
|
|
181
|
-
│ ├── storage/ # localStorage 操作(4个函数)
|
|
182
|
-
│ ├── copy/ # 深拷贝/浅拷贝(3个函数)
|
|
183
|
-
│ ├── array/ # 去重/排序/转换(6个函数)
|
|
184
|
-
│ ├── cookie/ # Cookie 操作(3个函数)
|
|
185
|
-
│ └── browser/ # URL参数/剪贴板/文件下载/滚动(9个函数)
|
|
186
|
-
├── tests/ # 单元测试
|
|
187
|
-
│ ├── is.test.ts
|
|
188
|
-
│ ├── format.test.ts
|
|
189
|
-
│ ├── storage.test.ts
|
|
190
|
-
│ ├── copy.test.ts
|
|
191
|
-
│ ├── array.test.ts
|
|
192
|
-
│ ├── cookie.test.ts
|
|
193
|
-
│ └── browser.test.ts
|
|
194
|
-
├── package.json # 包配置(入口、脚本、依赖)
|
|
195
|
-
├── tsconfig.json # TypeScript 编译配置
|
|
196
|
-
├── rolldown.config.js # 打包配置(Rolldown)
|
|
197
|
-
├── vitest.config.ts # 测试配置(Vitest)
|
|
198
|
-
├── pnpm-lock.yaml
|
|
199
|
-
└── dist/ # 构建输出(CJS + ESM + .d.ts)
|
|
200
|
-
```
|
|
144
|
+
- **`scrollToTop(behavior?)`** — 滚动到顶部(默认平滑)。 `scrollToTop()`
|
|
145
|
+
- **`scrollToBottom(behavior?)`** — 滚动到底部(默认平滑)。 `scrollToBottom()`
|
|
146
|
+
- **`onScroll(callback)`** — 监听滚动(rAF 节流),返回清理函数。 `const off = onScroll(y => console.log(y))`
|