/**
* @desc 获取 WXML 节点信息的对象
* @param {*} selector 选择器
* @param {*} com 自定义组件的实例对象,如在组件内使用必传
* @returns {promise}
*/
const getNodes = (selector, com) => {
const query = com ? com.createSelectorQuery() : wx.createSelectorQuery()
query.selectAll(selector).boundingClientRect()
return new Promise((reslove, reject) => {
query.exec(([res]) => {
res.length ? reslove(res) : reject()
})
})
}
/**
* @desc 获取某个月的天数
* @param {Number} month 如是getMonth()获取的月份 要加1
* @param {Number} year
* @returns {Number}
*/
function getDays(month = new Date().getMonth() + 1, year = new Date().getFullYear()) {
const date = new Date(`${year}-${++month}`)
date.setDate(0)
return date.getDate()
}
/**
* @desc 函数防抖
* @param {Function} func 目标函数
* @param {Number} delay 延迟执行毫秒数
* @param {Boolean} immediate true - 立即执行, false - 延迟执行
*/
function debounce(func, delay = 500, immediate) {
let timer;
return function () {
if (timer) clearTimeout(timer);
if (immediate) {
let callNow = !timer;
timer = setTimeout(() => {
timer = null;
}, delay);
if (callNow) func.apply(this, arguments);
return
}
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay)
}
}
/**
* @desc 函数节流
* @param {Function} func 目标函数
* @param {Number} delay 延迟执行毫秒数
* @param {Boolean} immediate true - 立即执行, false - 延迟执行
*/
function throttle(func, delay = 500, immediate) {
let timer = 0;
return function () {
if (immediate) {
const now = new Date().getTime();
if (now - timer > delay) {
func.apply(this, arguments)
timer = now
}
} else {
if (!timer) {
timer = setTimeout(() => {
timer = null;
func.apply(this, arguments)
}, delay)
}
}
}
}
/**
* @desc 日期格式化,将各种日期数据类型转为指定字符串格式
* @param {String,Number} date 日期字符串,可以是毫秒数
* @param {String} fmt 格式化参数
* @returns {string}
*/
function dateFormat(date, fmt = "YYYY-MM-DD hh:mm:ss") {
if (!date) {
return ""
}
if (typeof date === 'string') {
date = date.replace("-", "/");
}
date = new Date(date);
const o = {
"M+": date.getMonth() + 1, //月份
"D+": date.getDate(), //日
"h+": date.getHours(), //小时
"m+": date.getMinutes(), //分
"s+": date.getSeconds(), //秒
"q+": Math.floor((date.getMonth() + 3) / 3), //季度
"S": date.getMilliseconds() //毫秒
};
if (/(Y+)/.test(fmt)) {
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
}
for (const k in o) {
if (new RegExp("(" + k + ")").test(fmt)) {
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
}
}
return fmt;
}
/**
* @desc 判断两个对象内容是否相等
* @param {Object} a 对象1
* @param {Object} b 对象2
* @param {String} excludeProp 不检查某个字段
* @returns {Boolean}
*/
function isObjectValueEqual(a, b, excludeProp) {
var aProps = Object.getOwnPropertyNames(a).filter(x => x != excludeProp);
var bProps = Object.getOwnPropertyNames(b).filter(x => x != excludeProp);
if (aProps.length != bProps.length) {
return false;
}
for (var i = 0; i < aProps.length; i++) {
var propName = aProps[i]
var propA = a[propName]
var propB = b[propName]
// 先判断两边都有相同键名
if (!b.hasOwnProperty(propName)) return false
if ((propA instanceof Object)) {
if (isObjectValueEqual(propA, propB)) {
} else {
return false
}
} else if (propA !== propB) {
return false
} else { }
}
return true
}
/**
* @desc 递归实现深拷贝
* @param {*} obj
* @param {*} hash
*/
function deepClone(obj, hash = new WeakMap()) {
var cloneObj;
var Constructor = obj.constructor
switch (Constructor) {
case RegExp:
cloneObj = new Constructor(obj)
break
case Date:
cloneObj = new Constructor(obj.getTime())
break
default:
if (hash.has(obj)) return hash.get(obj)
cloneObj = new Constructor()
hash.set(obj, cloneObj)
}
for (const k in obj) {
var item = obj[k]
if (item && typeof item === 'object') {
cloneObj[k] = deepClone(item)
} else {
cloneObj[k] = item
}
}
return cloneObj
}
/**
* 深度合并两个对象
* @param obj1
* @param obj2
* @returns {*}
*/
function deepMerge(obj1, obj2) {
obj1 = deepClone(obj1)
Object.keys(obj2).forEach(key => {
obj1[key] = obj1[key] && obj1[key].toString() === "[object Object]" &&
(obj2[key] && obj2[key].toString() === "[object Object]")
? deepMerge(obj1[key], obj2[key])
: (obj1[key] = obj2[key]);
})
return obj1;
}
/**
* @desc 生成唯一标识符
* @returns {String}
*/
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
/**
* @desc 递归实现数组扁平化
* @param {Array} arr
* @returns {Array}
*/
function flatten(arr) {
return arr.reduce((prev, cur) => {
return prev.concat(Array.isArray(cur) ? flatten(cur) : cur);
}, [])
}
/**
* 生成指定范围随机数
* @param n
* @param m
* @returns {number}
*/
export function randomByScope(n, m) {
var result = Math.random() * (m - n) + n;
if (result === n) {
result = m;
}
return parseInt(result);
}
module.exports = {
dateFormat,
getDays,
debounce,
throttle,
deepClone,
deepMerge,
isObjectValueEqual,
randomByScope,
getNodes,
guid,
flatten
}