"添加前端模板和运行代码模块"
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
/**
|
||||
* 合并 Tailwind CSS 类名的工具函数
|
||||
* @param inputs - 类名数组或对象
|
||||
* @returns 合并后的类名字符串
|
||||
*/
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化日期
|
||||
* @param date - 日期对象或字符串
|
||||
* @param options - 格式化选项
|
||||
* @returns 格式化后的日期字符串
|
||||
*/
|
||||
export function formatDate(
|
||||
date: Date | string,
|
||||
options: Intl.DateTimeFormatOptions = {}
|
||||
): string {
|
||||
const dateObj = typeof date === 'string' ? new Date(date) : date;
|
||||
return new Intl.DateTimeFormat('zh-CN', {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
...options,
|
||||
}).format(dateObj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化数字
|
||||
* @param num - 数字
|
||||
* @param options - 格式化选项
|
||||
* @returns 格式化后的数字字符串
|
||||
*/
|
||||
export function formatNumber(
|
||||
num: number,
|
||||
options: Intl.NumberFormatOptions = {}
|
||||
): string {
|
||||
return new Intl.NumberFormat('zh-CN', options).format(num);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机 ID
|
||||
* @param length - ID 长度
|
||||
* @returns 随机 ID 字符串
|
||||
*/
|
||||
export function generateId(length: number = 8): string {
|
||||
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||
let result = '';
|
||||
for (let i = 0; i < length; i++) {
|
||||
result += chars.charAt(Math.floor(Math.random() * chars.length));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 防抖函数
|
||||
* @param func - 要防抖的函数
|
||||
* @param wait - 等待时间(毫秒)
|
||||
* @returns 防抖后的函数
|
||||
*/
|
||||
export function debounce<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
wait: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let timeout: NodeJS.Timeout;
|
||||
return (...args: Parameters<T>) => {
|
||||
clearTimeout(timeout);
|
||||
timeout = setTimeout(() => func(...args), wait);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 节流函数
|
||||
* @param func - 要节流的函数
|
||||
* @param limit - 时间限制(毫秒)
|
||||
* @returns 节流后的函数
|
||||
*/
|
||||
export function throttle<T extends (...args: any[]) => any>(
|
||||
func: T,
|
||||
limit: number
|
||||
): (...args: Parameters<T>) => void {
|
||||
let inThrottle: boolean;
|
||||
return (...args: Parameters<T>) => {
|
||||
if (!inThrottle) {
|
||||
func(...args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => (inThrottle = false), limit);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为移动设备
|
||||
* @returns 是否为移动设备
|
||||
*/
|
||||
export function isMobile(): boolean {
|
||||
if (typeof window === 'undefined') return false;
|
||||
return window.innerWidth < 768;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否为暗色模式
|
||||
* @returns 是否为暗色模式
|
||||
*/
|
||||
export function isDarkMode(): boolean {
|
||||
if (typeof window === 'undefined') return false;
|
||||
return document.documentElement.classList.contains('dark');
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换暗色模式
|
||||
*/
|
||||
export function toggleDarkMode(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
document.documentElement.classList.toggle('dark');
|
||||
localStorage.setItem('darkMode', document.documentElement.classList.contains('dark').toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化暗色模式
|
||||
*/
|
||||
export function initDarkMode(): void {
|
||||
if (typeof window === 'undefined') return;
|
||||
const saved = localStorage.getItem('darkMode');
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
|
||||
if (saved === 'true' || (saved === null && prefersDark)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user