typescript
/**
* 1. Debounce Function
* 防止在 scroll、resize 或 input change 等事件中被频繁触发。
*/
export function debounce<T extends (...args: any[]) => any>(
func: T,
delay: number = 300
): (...args: Parameters<T>) => void {
let timeout: NodeJS.Timeout;
return (...args: Parameters<T>) => {
clearTimeout(timeout);
timeout = setTimeout(() => func(...args), delay);
};
}
/**
* 2. Format Date to Readable String
* 再也不用去 Google 日期格式化了。
*/
export function formatDate(dateStr: string | Date, locale: string = "en-US"): string {
return new Date(dateStr).toLocaleDateString(locale, {
year: "numeric",
month: "short",
day: "numeric",
});
}
/**
* 3. ClassNames Utility
* 条件 class 不应该看起来一团糟。
*/
export function classNames(...args: (string | boolean | undefined | null)[]): string {
return args.filter(Boolean).join(" ");
}
/**
* 4. Safe JSON Parse
* 在处理格式错误的 localStorage 或 API 响应时,避免应用直接崩溃。
*/
export function safeJsonParse<T = any>(str: string | null, fallback: T): T {
if (!str) return fallback;
try {
return JSON.parse(str);
} catch {
return fallback;
}
}
/**
* 5. IsEmpty Object
* 比 Object.keys(obj).length === 0 更优雅。
*/
export function isEmpty(obj: any): boolean {
if (!obj) return true;
return Object.keys(obj).length === 0 && obj.constructor === Object;
}
/**
* 6. Copy to Clipboard
* 因为每个应用都会有一个“复制链接”的按钮。
*/
export async function copyToClipboard(text: string): Promise<boolean> {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
console.error("Copy failed:", err);
return false;
}
}
/**
* 7. Capitalize First Letter
* 一个很小的细节,但能明显提升质感。
*/
export function capitalize(str: string): string {
if (!str) return "";
return str.charAt(0).toUpperCase() + str.slice(1);
}
/**
* 8. Sleep Helper
* 适用于节流操作、loading 状态或动画。
*/
export function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* 9. Remove Duplicates From Array
* 零样板代码,保持数组干净。
*/
export function uniqueArray<T>(arr: T[]): T[] {
return [...new Set(arr)];
}
/**
* 10. Download Any File from URL
* 立即触发文件下载。
*/
export function downloadFile(url: string, filename: string): void {
const a = document.createElement("a");
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}使用示例
在项目其他地方引入即可:
typescript
import { debounce, formatDate, classNames } from "@/utils";
// 使用 debounce
const handleSearch = debounce((query: string) => {
console.log("Searching for:", query);
}, 500);
// 使用 formatDate
const today = formatDate(new Date(), "zh-CN");
// 使用 classNames
const btnClass = classNames("btn", isLoading && "btn-loading");