utils.js 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /**
  2. * @description 防抖
  3. * @param {Function} func 需要包装的函数
  4. * @param {string} wait 等待执行时间
  5. * @param {boolean} immediate 是否是立即执行 默认不立即执行
  6. * @returns {Function} 返回包装后的函数
  7. */
  8. export function debounce(func, wait, immediate = true) {
  9. let timeout, result
  10. return function() {
  11. const context = this
  12. const args = arguments
  13. if (timeout) clearTimeout(timeout)
  14. if (immediate) {
  15. const callNow = !timeout
  16. timeout = setTimeout(function() {
  17. timeout = null
  18. }, wait)
  19. if (callNow) result = func.apply(context, args)
  20. } else {
  21. timeout = setTimeout(function() {
  22. func.apply(context, args)
  23. }, wait)
  24. }
  25. return result
  26. }
  27. }
  28. /**
  29. * @description 节流
  30. * @param {Function} func 需要包装的函数
  31. * @param {string} wait 间隔时间
  32. * @returns {Function} 返回包装后的函数
  33. */
  34. export function throttle(func, wait) {
  35. let timeout
  36. return function() {
  37. const context = this
  38. const args = arguments
  39. if (!timeout) {
  40. timeout = setTimeout(function() {
  41. timeout = null
  42. func.apply(context, args)
  43. }, wait)
  44. }
  45. }
  46. }
  47. /**
  48. * @description 深度克隆
  49. * @param {object} obj 克隆目标
  50. * @returns {object} 返回目标对象深度克隆后的结果
  51. */
  52. export function deepClone(obj, cache = new WeakMap()) {
  53. if (typeof obj !== 'object') return obj // 普通类型,直接返回
  54. if (obj === null) return obj
  55. if (cache.get(obj)) return cache.get(obj) // 防止循环引用,程序进入死循环
  56. if (obj instanceof Date) return new Date(obj)
  57. if (obj instanceof RegExp) return new RegExp(obj)
  58. // 找到所属原型上的constructor,所属原型上的constructor指向当前对象的构造函数
  59. let cloneObj = new obj.constructor()
  60. cache.set(obj, cloneObj) // 缓存拷贝的对象,用于处理循环引用的情况
  61. for (let key in obj) {
  62. if (obj.hasOwnProperty(key)) {
  63. cloneObj[key] = deepClone(obj[key], cache) // 递归拷贝
  64. }
  65. }
  66. return cloneObj
  67. }
  68. /**
  69. * @description 时间日期格式化
  70. * @param {dateTime} date 标准时间格式 -> new Date()
  71. * @param {string} format 时间格式化的格式 'yyyy-MM-dd hh:mm:ss'
  72. * @returns {string} 格式化后的时间 '2017-01-01 01:00:00'
  73. */
  74. export function dateFormat(date = new Date(), format = 'yyyy-MM-dd hh:mm:ss') {
  75. var o = {
  76. 'M+': date.getMonth() + 1, // month
  77. 'd+': date.getDate(), // day
  78. 'h+': date.getHours(), // hour
  79. 'm+': date.getMinutes(), // minute
  80. 's+': date.getSeconds(), // second
  81. 'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
  82. S: date.getMilliseconds(), // millisecond
  83. }
  84. if (/(y+)/.test(format)) {
  85. format = format.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length))
  86. }
  87. for (var k in o) {
  88. if (new RegExp('(' + k + ')').test(format)) {
  89. format = format.replace(RegExp.$1, RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k])
  90. .length))
  91. }
  92. }
  93. return format
  94. }
  95. /**
  96. * @description 倒计时
  97. * @param diff 倒计时时间(s)
  98. * @param loadTime 运行时的当前时间(s)
  99. * @param item 倒计时对象 默认:{ speed: 1000 }
  100. * @param callback 回调
  101. */
  102. export function countDown(diff, loadTime, item, callback) {
  103. function round($diff) {
  104. let dd = parseInt($diff / 1000 / 60 / 60 / 24, 10) // 计算剩余的天数
  105. let hh = parseInt(($diff / 1000 / 60 / 60) % 24, 10) // 计算剩余的小时数
  106. let mm = parseInt(($diff / 1000 / 60) % 60, 10) // 计算剩余的分钟数
  107. let ss = parseInt(($diff / 1000) % 60, 10) // 计算剩余的秒数
  108. function checkTime(_a) {
  109. let a = _a
  110. if (a < 10) {
  111. a = '0' + a
  112. }
  113. return a.toString()
  114. }
  115. item.conttainer = {
  116. ddhh: checkTime(dd * 24 + hh),
  117. dd: checkTime(dd),
  118. hh: checkTime(hh),
  119. mm: checkTime(mm),
  120. ss: checkTime(ss)
  121. }
  122. if (
  123. item.conttainer.dd > 0 ||
  124. item.conttainer.hh > 0 ||
  125. item.conttainer.mm > 0 ||
  126. item.conttainer.ss > 0
  127. ) {
  128. item.t = setTimeout(function() {
  129. round($diff - (item.speed || 1000))
  130. }, item.speed || 1000)
  131. }
  132. // 回调
  133. callback && callback(item)
  134. }
  135. round(diff - loadTime)
  136. }
  137. /* 对象循环赋值 */
  138. export function objAssign(target = {}, source = {}) {
  139. for (let key in target) {
  140. if (source.hasOwnProperty(key)) {
  141. target[key] = source[key]
  142. }
  143. }
  144. }
  145. /* 数组去重 */
  146. export function arrayUnique(arr) {
  147. if (!Array.isArray(arr)) {
  148. console.log('type error!')
  149. return
  150. }
  151. return Array.from(new Set(arr))
  152. }
  153. /*
  154. * 反序列化URL参数
  155. * { age: "25", name: "Tom" }
  156. */
  157. export function parseUrlSearch(location) {
  158. return location.search
  159. .replace(/(^\?)|(&$)/g, '')
  160. .split('&')
  161. .reduce((t, v) => {
  162. const [key, val] = v.split('=')
  163. t[key] = decodeURIComponent(val)
  164. return t
  165. }, {})
  166. }
  167. /*
  168. * getQueryParams('id')
  169. * 获取url上某个key的值
  170. */
  171. export function getParam(param) {
  172. // 获取浏览器参数
  173. const r = new RegExp(`\\?(?:.+&)?${param}=(.*?)(?:&.*)?$`)
  174. const m = window.location.toString().match(r)
  175. return m ? decodeURI(m[1]) : ''
  176. }
  177. /*
  178. * queryStringify
  179. * 将k-v的对象序列化转成 url?k=v&k1=v1;
  180. */
  181. export function queryStringify(search = {}) {
  182. return Object.entries(search)
  183. .reduce((t, v) => `${t}${v[0]}=${encodeURIComponent(v[1])}&`, '')
  184. .replace(/&$/, '')
  185. }
  186. /*
  187. * queryStringify
  188. * 将url?k=v&k1=v1的序列化转成k-v对象
  189. */
  190. export function queryParse(query = '') {
  191. if (query.startsWith('?')) {
  192. query = query.slice(0)
  193. }
  194. const obj = Object.create(null)
  195. query.split('&').forEach(str => {
  196. const v = str.split('=')
  197. obj[v[0]] = v[1]
  198. })
  199. return obj
  200. }