UNPKG

wangbd-myui

Version:

MY前端基础框架核心组件库

221 lines (191 loc) 5.54 kB
/** * 提供常用辅助函数 * @module $ui/utils/util */ const _isEqual = require('lodash/isEqual') const _get = require('lodash/get') const _set = require('lodash/set') const _cloneDeep = require('lodash/cloneDeep') // requestAnimationFrame 适配函数 const raFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || function (callback) { return window.setTimeout(callback, 1000 / 60); }; /** * 动画延时函数 * @function * @param {function} callback 动画回调函数 * @return {number} id 标识 * * @example * * import {requestAnimationFrame} from '$ui/utils/util' * requestAnimationFrame(() => { * // do sth .... * * }) */ export const requestAnimationFrame = raFrame /** * 清除动画延时 * @function * @param {number} id 标识 * * @example * * import {requestAnimationFrame, cancelAnimationFrame} from '$ui/utils/util' * const id = requestAnimationFrame(()= > { * // do sth * }) * cancelAnimationFrame(id) */ export const cancelAnimationFrame = window.cancelAnimationFrame || window.webkitRequestAnimationFrame || function (id) { window.clearTimeout(id); }; /** * 判断两个对象是否相等 * @param {*} object 对象1 * @param {*} other 对象2 * @return {boolean} */ export function isEqual(object, other) { return _isEqual(object, other) } /** * 防抖函数 * @param {function} fn 事件处理函数 * @param {number} [delay=20] 延迟时间 * @param {boolean} [isImmediate=false] 是否立刻执行 * @param {object} [context=this] 上下文对象 * @returns {Function} 事件处理函数 */ export function debounce(fn, delay = 20, isImmediate = false, context = this) { // 使用闭包,保存执行状态,控制函数调用顺序 let timer; return function () { const _args = [].slice.call(arguments) clearTimeout(timer); const _fn = function () { timer = null; if (!isImmediate) fn.apply(context, _args); }; // 是否滚动时立刻执行 const callNow = !timer && isImmediate; timer = setTimeout(_fn, delay); if (callNow) fn.apply(context, _args); } } /** * 节流函数 * @param {function} fn 事件处理函数 * @param {object} [context=this] 上下文对象 * @param {boolean} [isImmediate=false] 是否立刻执行 * @returns {Function} 事件处理函数 */ export function throttle(fn, context = this, isImmediate = false) { let isLocked; return function () { const _args = arguments if (isLocked) return isLocked = true raFrame(function () { isLocked = false; fn.apply(context, _args) }) isImmediate && fn.apply(context, _args) } } /** * 生成随机GUID * @return {string} */ export function guid() { return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { const r = Math.random() * 16 | 0, v = c === 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }).toUpperCase(); } /** * 生成唯一id * @return {string} */ export function uid() { const rnd = Math.floor(Math.random() * 1000) const timestamp = new Date().getTime() return [timestamp, rnd].join('') } /** * 根据path查找对象或数组中的某个属性 * @param {object|array} object 要检索的对象 * @param {string|array} path 要获取属性的路径 * @param {string} [defaultValue] 如果解析值是 undefined ,这值会被返回。 * @return {undefined|*} * * @example * * import {get} from '$ui/utils/util' * const object = { 'a': [{ 'b': { 'c': 3 } }] }; * get(object, 'a[0].b.c') // -> 3 */ export function get(object, path, defaultValue) { return _get(object, path, defaultValue) } /** * 设置 object对象中对应 path 属性路径上的值,如果path不存在,则创建。 缺少的索引属性会创建为数组,而缺少的属性会创建为对象 * @param {object} object 要修改的对象 * @param {string|array} path 要设置的对象路径 * @param {*} value 要设置的值 */ export function set(object, path, value) { return _set(object, path, value) } /** * 深拷贝 * @param {*} value 要深拷贝的值 * @return {*} 返回拷贝后的值 */ export function cloneDeep(value) { return _cloneDeep(value) } /** * 对数组按制定字段名称进行分组 * @param {Array} data 数组数组 * @param {string} [field=group] 分组字段名称 * @returns {object} 结果 * * @example * [{name:1, group:'a'},{name:2, group:'a'}, {name:3, group:'b'}] -> * { * 'a':[{name:1, group:'a'}, {name:2, group:'a'}] * 'b': [{name:3, group:'b'}] * } */ export function grouping(data = [], field = 'group') { const result = { default: [] } data.forEach(item => { const group = item[field] if (group) { if (!result[group]) { result[group] = [] } result[group].push(item) } else { result.default.push(item) } }) return result } /** * 分页获取数据 * @param {Array} data 源数据 * @param {number} [page=1] 当前页面,1开始 * @param {number} [size=10] 页大小,默认10 * @return {Array} */ export function pager(data, page = 1, size = 10) { if (!data) return [] const start = (page - 1) * size const end = start + size return data.length > start ? data.slice(start, end) : [] }