FED常用工具方法
常用工具方法
实现数组去重
参考地址:https://github.com/mqyqingfeng/Blog/issues/27
非通用方法,需要知道object中的主键,可避免object中key顺序变化而导致的异常情况,下面以id为例
unique (array) {
// res用来存储结果
let res = []
for (let i = 0, arrayLen = array.length; i < arrayLen; i++) {
let j = 0
let resLen = res.length
for (; j < resLen; j++) {
if (array[i].id === res[j].id) {
break
}
}
if (j === resLen) {
res.push(array[i])
}
}
return res
}
unique (array) {
let hash = {}
array.forEach((v, i) => hash[[JSON.stringify(v)]] = i)
let keys = Object.keys(hash)
let list = keys.sort((a, b) => hash[a] > hash[b]).map(item => JSON.parse(item))
return list
}
Tools
/**
* 格式化日期时间
* @time new Date对象或时间戳或日期格式字符串
* @cFormat 指定格式
*/
export function parseTime (time, cFormat) {
if (arguments.length === 0) {
return null
}
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
let date
if (typeof time === 'object') {
date = time
} else {
if (('' + time).length === 10) time = parseInt(time) * 1000
date = new Date(time)
}
const formatObj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
i: date.getMinutes(),
s: date.getSeconds(),
a: date.getDay()
}
const timeStr = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
let value = formatObj[key]
if (key === 'a') return ['日', '一', '二', '三', '四', '五', '六'][value]
if (result.length > 0 && value < 10) {
value = '0' + value
}
return value || 0
})
return timeStr
}
/**
* 格式化时间, 距离当前时间多久前
* @time 单位s
* @option 指定格式
* */
export function formatTime (time, option) {
time = +time * 1000
const d = new Date(time)
const now = Date.now()
const diff = (now - d) / 1000
if (diff < 30) {
return '刚刚'
} else if (diff < 3600) { // less 1 hour
return Math.ceil(diff / 60) + '分钟前'
} else if (diff < 3600 * 24) {
return Math.ceil(diff / 3600) + '小时前'
} else if (diff < 3600 * 24 * 2) {
return '1天前'
}
if (option) {
return parseTime(time, option)
} else {
return d.getMonth() + 1 + '月' + d.getDate() + '日' + d.getHours() + '时' + d.getMinutes() + '分'
}
}
/*
* 日期范围选择器
* */
export const pickerOptions = [
{
text: '今天',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const end = addDate(today)
picker.$emit('pick', [today, end])
}
}, {
text: '最近一周',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const start = today - 3600 * 1000 * 24 * 7, end = addDate(today)
picker.$emit('pick', [start, end])
}
}, {
text: '最近一个月',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const start = today - 3600 * 1000 * 24 * 30, end = addDate(today)
picker.$emit('pick', [start, end])
}
}, {
text: '最近三个月',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const start = today - 3600 * 1000 * 24 * 90, end = addDate(today)
picker.$emit('pick', [start, end])
}
}]
/*
* 增加一天,然后减1s
* */
function addDate (now, day) {
now = new Date(now)
return +now.setDate(now.getDate() + (day || 1)) - 1000
}
/**
* 获取url参数
* @url url地址,默认可不传
* */
export function getQueryObject (url) {
url = url == null ? window.location.href : url
const search = url.substring(url.lastIndexOf('?') + 1)
const obj = {}
const reg = /([^?&=]+)=([^?&=]*)/g
search.replace(reg, (rs, $1, $2) => {
const name = decodeURIComponent($1)
let val = decodeURIComponent($2)
val = String(val)
obj[name] = val
return rs
})
return obj
}
/**
* 获取字节长度
* @param {Sting} val 输入值
* @returns {number} 返回值
*/
export function getByteLen (val) {
let len = 0
for (let i = 0; i < val.length; i++) {
if (val[i].match(/[^\x00-\xff]/ig) != null) {
len += 1
} else {
len += 0.5
}
}
return Math.floor(len)
}
/**
* 删除数组中无用的值,如undefined、null、''等
* @arr 要处理的数组
* */
export function cleanArray (arr) {
return arr.filter(v => v)
}
/*
* 数组去重
* */
export function uniqueArr (arr) {
return Array.from(new Set(arr))
}
/**
* 序列化json对象
* */
export function param (json) {
if (!json) return ''
return cleanArray(Object.keys(json).map(key => {
if (json[key] === undefined) return ''
return encodeURIComponent(key) + '=' +
encodeURIComponent(json[key])
})).join('&')
}
/**
* 转化json字符串为对象
* */
export function param2Obj (url) {
const search = url.split('?')[1]
if (!search) {
return {}
}
return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
}
/*
* 获取html字符串中的文本
* */
export function html2Text (val) {
const div = document.createElement('div')
div.innerHTML = val
return div.textContent || div.innerText
}
/*
* 对象合并
* */
export function objectMerge (target, source) {
if (typeof target !== 'object') {
target = {}
}
if (Array.isArray(source)) {
return source.slice()
}
Object.keys(source).forEach((property) => {
const sourceProperty = source[property]
if (typeof sourceProperty === 'object') {
target[property] = objectMerge(target[property], sourceProperty)
} else {
target[property] = sourceProperty
}
})
return target
}
/**
* 对象深度拷贝,避免引用关系
*/
export function deepClone (source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'shallowClone')
}
const targetObj = source.constructor === Array ? [] : {}
Object.keys(source).forEach((keys) => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
})
return targetObj
}
/*
* 节流函数
* */
export function debounce (func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function () {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔last小于设定时间间隔wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
return function (...args) {
context = this
timestamp = +new Date()
const callNow = immediate && !timeout
// 如果延时不存在,重新设定延时
if (!timeout) timeout = setTimeout(later, wait)
if (callNow) {
result = func.apply(context, args)
context = args = null
}
return result
}
}
/*
* 工具类方法
* */
/*
* 增加一天,然后减1s
* */
function addDate (now, day) {
now = new Date(now)
return +now.setDate(now.getDate() + (day || 1)) - 1000
}
export default {
/*
* 计算某一列每一行要合并的单元格行数
* 示例:
* this.rowSpan = this.getCellMergeArray(data, 'name');
* objectSpanMethod({row, column, rowIndex, columnIndex}) {
* if (columnIndex === 0) {return [this.rowSpan[rowIndex], 1]};
* }
* */
getCellMergeArray (data, key) {
let spanArr = [], pos
for (let i = 0; i < data.length; i++) {
if (i === 0) {
spanArr.push(1)
pos = 0
} else {
// 判断当前元素与上一个元素是否相同
if (data[i][key] === data[i - 1][key]) {
spanArr[pos] += 1
spanArr.push(0)
} else {
spanArr.push(1)
pos = i
}
}
}
return spanArr
},
// 日期范围选择器扩展
Shortcuts () {
return [{
text: '今天',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const end = addDate(today)
picker.$emit('pick', [today, end])
}
}, {
text: '最近一周',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const start = today - 3600 * 1000 * 24 * 7, end = addDate(today)
picker.$emit('pick', [start, end])
}
}, {
text: '最近一个月',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const start = today - 3600 * 1000 * 24 * 30, end = addDate(today)
picker.$emit('pick', [start, end])
}
}, {
text: '最近三个月',
onClick (picker) {
const today = +new Date(new Date().toDateString())
const start = today - 3600 * 1000 * 24 * 90, end = addDate(today)
picker.$emit('pick', [start, end])
}
}]
},
// 4舍5入
toFixed (value = 0, precision = 2) {
const multiple = Math.pow(10, precision)
return (Math.round(value * multiple) / multiple)
},
/**
** 加法函数,用来得到精确的加法结果
** 说明:javascript的加法结果会有误差,在两个浮点数相加的时候会比较明显。这个函数返回较为精确的加法结果。
** 调用:accAdd(arg1,arg2)
** 返回值:arg1加上arg2的精确结果
**/
accAdd (arg1, arg2) {
let r1, r2, m, c
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
c = Math.abs(r1 - r2)
m = Math.pow(10, Math.max(r1, r2))
if (c > 0) {
let cm = Math.pow(10, c)
if (r1 > r2) {
arg1 = Number(arg1.toString().replace('.', ''))
arg2 = Number(arg2.toString().replace('.', '')) * cm
} else {
arg1 = Number(arg1.toString().replace('.', '')) * cm
arg2 = Number(arg2.toString().replace('.', ''))
}
} else {
arg1 = Number(arg1.toString().replace('.', ''))
arg2 = Number(arg2.toString().replace('.', ''))
}
return (arg1 + arg2) / m
},
/**
** 减法函数,用来得到精确的减法结果
** 说明:javascript的减法结果会有误差,在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
** 调用:accSub(arg1,arg2)
** 返回值:arg1加上arg2的精确结果
**/
accSub (arg1, arg2) {
let r1, r2, m, n
try {
r1 = arg1.toString().split('.')[1].length
} catch (e) {
r1 = 0
}
try {
r2 = arg2.toString().split('.')[1].length
} catch (e) {
r2 = 0
}
m = Math.pow(10, Math.max(r1, r2)) // last modify by deeka //动态控制精度长度
n = (r1 >= r2) ? r1 : r2
return ((arg1 * m - arg2 * m) / m).toFixed(n)
},
/**
** 乘法函数,用来得到精确的乘法结果
** 说明:javascript的乘法结果会有误差,在两个浮点数相乘的时候会比较明显。这个函数返回较为精确的乘法结果。
** 调用:accMul(arg1,arg2)
** 返回值:arg1乘以 arg2的精确结果
**/
accMul (arg1, arg2) {
let m = 0, s1 = arg1.toString(), s2 = arg2.toString()
try {
m += s1.split('.')[1].length
} catch (e) {
}
try {
m += s2.split('.')[1].length
} catch (e) {
}
return Number(s1.replace('.', '')) * Number(s2.replace('.', '')) / Math.pow(10, m)
},
/**
** 除法函数,用来得到精确的除法结果
** 说明:javascript的除法结果会有误差,在两个浮点数相除的时候会比较明显。这个函数返回较为精确的除法结果。
** 调用:accDiv(arg1,arg2)
** 返回值:arg1除以arg2的精确结果
**/
accDiv (arg1, arg2) {
let t1 = 0, t2 = 0, r1, r2
try {
t1 = arg1.toString().split('.')[1].length
} catch (e) {
}
try {
t2 = arg2.toString().split('.')[1].length
} catch (e) {
}
r1 = Number(arg1.toString().replace('.', ''))
r2 = Number(arg2.toString().replace('.', ''))
return (r1 / r2) * Math.pow(10, t2 - t1)
}
}