UNPKG

kpmg-smart-table

Version:
148 lines (130 loc) 3.59 kB
/** * 防抖函数 * @param {Function} fn 需要防抖的函数 * @param {Number} delay 延迟时间(ms) * @returns {Function} 防抖处理后的函数 */ export function debounce(fn, delay = 300) { let timer = null; return function(...args) { if (timer) clearTimeout(timer); timer = setTimeout(() => { fn.apply(this, args); timer = null; }, delay); }; } /** * 节流函数 * @param {Function} fn 需要节流的函数 * @param {Number} wait 等待时间(ms) * @returns {Function} 节流处理后的函数 */ export function throttle(fn, wait = 300) { let previous = 0; let timer = null; return function(...args) { const now = Date.now(); const remaining = wait - (now - previous); if (remaining <= 0 || remaining > wait) { if (timer) { clearTimeout(timer); timer = null; } previous = now; fn.apply(this, args); } else if (!timer) { timer = setTimeout(() => { previous = Date.now(); timer = null; fn.apply(this, args); }, remaining); } }; } /** * 函数缓存 * @param {Function} fn 需要缓存的函数 * @returns {Function} 缓存处理后的函数 */ export function memoize(fn) { const cache = new Map(); return function(...args) { const key = JSON.stringify(args); if (cache.has(key)) { return cache.get(key); } const result = fn.apply(this, args); cache.set(key, result); return result; }; } /** * RAF节流 * 使用requestAnimationFrame实现的节流函数 * @param {Function} fn 需要节流的函数 * @returns {Function} 节流处理后的函数 */ export function rafThrottle(fn) { let locked = false; return function(...args) { if (locked) return; locked = true; window.requestAnimationFrame(() => { fn.apply(this, args); locked = false; }); }; } /** * 计算字符串显示宽度(粗略) * 用于表格自动宽度计算 * @param {String} str 要计算的字符串 * @returns {Number} 字符宽度(px) */ export function calcTextWidth(str) { if (!str) return 0; // 英文字符和数字宽度为10px, 中文字符宽度为18px let width = 0; for (let i = 0; i < str.length; i++) { const char = str.charCodeAt(i); // 中文字符范围 if (char >= 0x4e00 && char <= 0x9fa5) { width += 18; } else { width += 10; } } return width; } /** * 自动计算表格列宽 * @param {String} fieldName 字段名 * @param {Array} data 表格数据 * @param {String} title 列标题 * @param {Number} min 最小宽度 * @param {Number} max 最大宽度 * @returns {Number} 建议列宽 */ export function flexColumnWidth(fieldName, data = [], title = '', min = 80, max = 250) { // 标题宽度 const titleWidth = calcTextWidth(title) + 30; // 30px为内边距 if (!fieldName || !data || !data.length) { return Math.max(min, titleWidth); } // 内容最大宽度 let maxContentWidth = 0; for (let i = 0; i < data.length; i++) { const item = data[i]; const value = item[fieldName]; if (value !== undefined && value !== null) { const valueStr = value.toString(); const currentWidth = calcTextWidth(valueStr) + 30; // 30px为内边距 maxContentWidth = Math.max(maxContentWidth, currentWidth); } } // 取标题宽度和内容宽度的最大值 const suggestedWidth = Math.max(titleWidth, maxContentWidth); // 限制在最小和最大宽度之间 return Math.min(max, Math.max(min, suggestedWidth)); }