Skip to content

Commit 243559f

Browse files
committed
docs: 添加场景解决方案文档和导航
- 新增场景解决方案文档,展示常见需求的传统写法与使用 nex-lib 的对比 - 在首页、导航栏和指南目录中添加解决方案入口 - 补充 HTTP API 文档中的代码示例
1 parent 7cefde6 commit 243559f

File tree

5 files changed

+215
-0
lines changed

5 files changed

+215
-0
lines changed

docs/.vitepress/config.mts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,12 @@ export default defineConfig({
3838
{ text: '为什么选择 NexLib', link: '/guide/why' },
3939
]
4040
},
41+
{
42+
text: '方案',
43+
items: [
44+
{ text: '场景解决方案', link: '/guide/scenarios' }
45+
]
46+
},
4147
{
4248
text: 'API',
4349
items: [

docs/guide/api-http.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,43 @@ await Http.get('https://example.com/api', { query: { q: 'x' }, timeoutMs: 1000 }
1919
## withQuery(url, params)
2020
- 将对象转为查询参数并拼接到 URL
2121

22+
::: code-group
23+
```ts [Example]
24+
import { withQuery } from 'nex-lib'
25+
withQuery('https://a.com/path', { a: 1, b: true, c: null })
26+
```
27+
```text [Output]
28+
https://a.com/path?a=1&b=true
29+
```
30+
:::
31+
2232
## toFormData(obj)
2333
- 将对象转为 `FormData`,值为对象时自动 JSON 序列化
2434

35+
::: code-group
36+
```ts [Example]
37+
import { toFormData } from 'nex-lib'
38+
const fd = toFormData({ a: 1, b: 'x', c: { k: 'v' } })
39+
```
40+
```text [Output]
41+
FormData(a=1, b=x, c={"k":"v"}) // 展示性输出,实际为原生 FormData
42+
```
43+
:::
44+
2545
## withTimeout(promise, ms)
2646
- 为任意 Promise 添加超时(抛出 `Timeout` 错误)
2747

48+
::: code-group
49+
```ts [Example]
50+
import { withTimeout } from 'nex-lib'
51+
const p = new Promise(resolve => setTimeout(resolve, 50))
52+
await withTimeout(p, 10)
53+
```
54+
```text [Output]
55+
Error: Timeout
56+
```
57+
:::
58+
2859
## withRetry(fn, times, delay)
2960
- 重试封装;与 `ObjectUtils.retry` 一致
3061

docs/guide/index.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ const { format, getTimestamp, createWURL, ObjectUtils, StringUtils, ValidationUt
102102
<h3>URL</h3>
103103
<p>主域名、查询参数解析/追加、协议/路径/端口。</p>
104104
</a>
105+
<a class="card" href="/guide/scenarios">
106+
<h3>Solutions</h3>
107+
<p>场景解决方案:代码节省对比与最佳实践。</p>
108+
</a>
105109
<a class="card" href="/guide/api-http">
106110
<h3>HTTP</h3>
107111
<p>轻量 fetch 封装:超时/重试/查询/FormData。</p>

docs/guide/scenarios.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
outline: deep
3+
---
4+
5+
# 场景解决方案(Solutions)
6+
7+
从真实业务出发,展示“常见需求的传统写法 vs 使用 nex-lib 的写法”,并给出代码节省量参考。
8+
9+
## 1)搜索框防抖(避免频繁请求)
10+
11+
::: code-group
12+
```ts [Before]
13+
let timer: any
14+
function onInput(e: Event) {
15+
const q = (e.target as HTMLInputElement).value
16+
if (timer) clearTimeout(timer)
17+
timer = setTimeout(() => {
18+
fetch(`/api/search?q=${encodeURIComponent(q)}`)
19+
}, 300)
20+
}
21+
```
22+
```ts [After]
23+
import { ObjectUtils } from 'nex-lib'
24+
const doSearch = ObjectUtils.debounce((q: string) => {
25+
fetch(`/api/search?q=${encodeURIComponent(q)}`)
26+
}, 300)
27+
function onInput(e: Event) { doSearch((e.target as HTMLInputElement).value) }
28+
```
29+
```text [Reduction]
30+
约 12 行 → 4 行,节省 ~8 行
31+
```
32+
:::
33+
34+
## 2)列表分页请求(查询参数 + 超时 + 重试)
35+
36+
::: code-group
37+
```ts [Before]
38+
const url = new URL('/api/list', location.origin)
39+
url.searchParams.set('page', String(page))
40+
url.searchParams.set('size', String(size))
41+
const ac = new AbortController()
42+
const t = setTimeout(() => ac.abort(), 3000)
43+
try {
44+
let tries = 0
45+
while (tries < 3) {
46+
try {
47+
const res = await fetch(url.toString(), { signal: ac.signal })
48+
if (!res.ok) throw new Error('http')
49+
return await res.json()
50+
} catch (e) { tries++; await new Promise(r => setTimeout(r, 500)) }
51+
}
52+
} finally { clearTimeout(t) }
53+
```
54+
```ts [After]
55+
import { Http } from 'nex-lib'
56+
await Http.get('/api/list', {
57+
query: { page, size },
58+
timeoutMs: 3000,
59+
retry: { times: 3, delay: 500 },
60+
})
61+
```
62+
```text [Reduction]
63+
约 28 行 → 6 行,节省 ~22 行
64+
```
65+
:::
66+
67+
## 3)产品页 URL 参数管理(追加/替换/移除)
68+
69+
::: code-group
70+
```ts [Before]
71+
const u = new URL(location.href)
72+
u.searchParams.set('sku', sku)
73+
u.searchParams.set('ref', ref)
74+
history.replaceState(null, '', u.toString())
75+
```
76+
```ts [After]
77+
import { createWURL } from 'nex-lib'
78+
const u = createWURL(location.href)
79+
history.replaceState(null, '', u.replaceParams({ sku, ref }))
80+
```
81+
```text [Reduction]
82+
约 8 行 → 3 行,节省 ~5 行
83+
```
84+
:::
85+
86+
## 4)登录态存储与过期(TTL)
87+
88+
::: code-group
89+
```ts [Before]
90+
localStorage.setItem('token', JSON.stringify({ v: token, expireAt: Date.now()+86400000 }))
91+
const raw = localStorage.getItem('token')
92+
if (raw) {
93+
const obj = JSON.parse(raw)
94+
if (Date.now() >= obj.expireAt) localStorage.removeItem('token')
95+
}
96+
```
97+
```ts [After]
98+
import { StorageUtils } from 'nex-lib'
99+
StorageUtils.setWithTTL('token', token, 86400000)
100+
StorageUtils.getWithTTL('token')
101+
```
102+
```text [Reduction]
103+
约 9 行 → 2 行,节省 ~7 行
104+
```
105+
:::
106+
107+
## 5)倒计时与相对时间(展示友好)
108+
109+
::: code-group
110+
```ts [Before]
111+
function fmt(ms: number) {
112+
const s = Math.floor(ms/1000)
113+
const h = String(Math.floor((s%86400)/3600)).padStart(2,'0')
114+
const m = String(Math.floor((s%3600)/60)).padStart(2,'0')
115+
const sec = String(s%60).padStart(2,'0')
116+
return `${h}:${m}:${sec}`
117+
}
118+
```
119+
```ts [After]
120+
import { formatDuration, relativeTime, nowSeconds } from 'nex-lib'
121+
formatDuration(65000)
122+
relativeTime(nowSeconds()-120)
123+
```
124+
```text [Reduction]
125+
约 8 行 → 2 行,节省 ~6 行
126+
```
127+
:::
128+
129+
## 6)复制分享链接(兼容权限)
130+
131+
::: code-group
132+
```ts [Before]
133+
const ta = document.createElement('textarea')
134+
ta.value = url
135+
document.body.appendChild(ta)
136+
ta.select()
137+
document.execCommand('copy')
138+
document.body.removeChild(ta)
139+
```
140+
```ts [After]
141+
import { browserUtils } from 'nex-lib'
142+
await browserUtils.copyToClipboard(url)
143+
```
144+
```text [Reduction]
145+
约 6 行 → 1 行,节省 ~5 行
146+
```
147+
:::
148+
149+
## 7)主题色工具(对比色与亮暗)
150+
151+
::: code-group
152+
```ts [Before]
153+
function yiq(hex: string) {
154+
const h = hex.replace('#','')
155+
const r = parseInt(h.slice(0,2),16)
156+
const g = parseInt(h.slice(2,4),16)
157+
const b = parseInt(h.slice(4,6),16)
158+
const v = (r*299 + g*587 + b*114)/1000
159+
return v >= 128 ? '#000' : '#fff'
160+
}
161+
```
162+
```ts [After]
163+
import { ColorUtils } from 'nex-lib'
164+
ColorUtils.contrastColor('#ffcc00')
165+
ColorUtils.lighten('#333333', 0.5)
166+
ColorUtils.darken('#cccccc', 0.5)
167+
```
168+
```text [Reduction]
169+
约 10 行 → 3 行,节省 ~7 行
170+
```
171+
:::

docs/index.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ hero:
1616
- theme: brand
1717
text: API Docs
1818
link: /guide/api-time
19+
- theme: brand
20+
text: Solutions
21+
link: /guide/scenarios
1922
- theme: alt
2023
text: Why Nex Lib?
2124
link: /guide/why

0 commit comments

Comments
 (0)