utils.js 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /**
  2. * 全局工具类
  3. */
  4. /**
  5. * 进行延时,以达到可以简写代码的目的
  6. */
  7. export const sleep = (value = 30) => {
  8. return new Promise((resolve) => {
  9. setTimeout(() => {
  10. resolve()
  11. }, value)
  12. })
  13. }
  14. // 获取父组件的参数,因为支付宝小程序不支持provide/inject的写法
  15. // this.$parent在非H5中,可以准确获取到父组件,但是在H5中,需要多次this.$parent.$parent.xxx
  16. // 这里默认值等于undefined有它的含义,因为最顶层元素(组件)的$parent就是undefined,意味着不传name
  17. // 值(默认为undefined),就是查找最顶层的$parent
  18. export const $parent = (name = undefined) => {
  19. let parent = this.$parent
  20. // 通过while历遍,这里主要是为了H5需要多层解析的问题
  21. while (parent) {
  22. // 父组件
  23. if (parent.$options && parent.$options.name !== name) {
  24. // 如果组件的name不相等,继续上一级寻找
  25. parent = parent.$parent
  26. } else {
  27. return parent
  28. }
  29. }
  30. return false
  31. }
  32. // json数据克隆
  33. export const jsonClone = (obj) => {
  34. // 对常见的“非”值,直接返回原来值
  35. return JSON.parse(JSON.stringify(obj));
  36. }
  37. // 深度克隆
  38. export const deepClone = (obj) => {
  39. // 对常见的“非”值,直接返回原来值
  40. if ([null, undefined, NaN, false].includes(obj)) return obj
  41. if (typeof obj !== 'object' && typeof obj !== 'function') {
  42. // 原始类型直接返回
  43. return obj
  44. }
  45. const o = test.array(obj) ? [] : {}
  46. for (const i in obj) {
  47. if (obj.hasOwnProperty(i)) {
  48. o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i]
  49. }
  50. }
  51. return o
  52. }
  53. /**
  54. * 防抖函数
  55. */
  56. export const debounce = (fn, context, delay = 500) => {
  57. let timer
  58. return function(...args) {
  59. if (timer) {
  60. clearTimeout(timer)
  61. }
  62. timer = setTimeout(() => {
  63. fn.apply(context, args)
  64. }, delay)
  65. }
  66. }
  67. /**
  68. * 节流函数
  69. */
  70. export const throttle = (fn, context, wait = 500) => {
  71. let flag = true;
  72. return function(...args) {
  73. if (flag) {
  74. flag = false;
  75. fn.apply(context, args); //立即执行
  76. setTimeout(() => {
  77. flag = true
  78. }, wait)
  79. }
  80. }
  81. }
  82. /**
  83. * 根据属性数组创建一个新对象
  84. * @param {Object} obj 对象数据
  85. * @param { Array} keys 需要提取的字段集合
  86. */
  87. export const createMap = (obj, keys) => {
  88. return keys.reduce((result, key) => {
  89. if (obj.hasOwnProperty(key)) {
  90. result[key] = obj[key];
  91. }
  92. return result;
  93. }, {});
  94. }
  95. /**
  96. * @description 格式化时间
  97. * @param {String|Number} dateTime 需要格式化的时间戳
  98. * @param {String} fmt 格式化规则 yyyy:mm:dd|yyyy:mm|yyyy年mm月dd日|yyyy年mm月dd日 hh时MM分等 ss 秒,可自定义组合 默认yyyy-mm-dd
  99. * @returns {string} 返回格式化后的字符串
  100. */
  101. export function timeFormat(dateTime = null, formatStr = 'yyyy-mm-dd') {
  102. let date
  103. // 若传入时间为假值,则取当前时间
  104. if (!dateTime) {
  105. date = new Date()
  106. }
  107. // 若为unix秒时间戳,则转为毫秒时间戳(逻辑有点奇怪,但不敢改,以保证历史兼容)
  108. else if (/^\d{10}$/.test(dateTime?.toString().trim())) {
  109. date = new Date(dateTime * 1000)
  110. }
  111. // 若用户传入字符串格式时间戳,new Date无法解析,需做兼容
  112. else if (typeof dateTime === 'string' && /^\d+$/.test(dateTime.trim())) {
  113. date = new Date(Number(dateTime))
  114. }
  115. // 其他都认为符合 RFC 2822 规范
  116. else {
  117. // 处理平台性差异,在Safari/Webkit中,new Date仅支持/作为分割符的字符串时间
  118. date = new Date(
  119. typeof dateTime === 'string' ?
  120. dateTime.replace(/-/g, '/') :
  121. dateTime
  122. )
  123. }
  124. const timeSource = {
  125. 'y': date.getFullYear().toString(), // 年
  126. 'm': (date.getMonth() + 1).toString().padStart(2, '0'), // 月
  127. 'd': date.getDate().toString().padStart(2, '0'), // 日
  128. 'h': date.getHours().toString().padStart(2, '0'), // 时
  129. 'M': date.getMinutes().toString().padStart(2, '0'), // 分
  130. 's': date.getSeconds().toString().padStart(2, '0') // 秒
  131. // 有其他格式化字符需求可以继续添加,必须转化成字符串
  132. }
  133. for (const key in timeSource) {
  134. const [ret] = new RegExp(`${key}+`).exec(formatStr) || []
  135. if (ret) {
  136. // 年可能只需展示两位
  137. const beginIndex = key === 'y' && ret.length === 2 ? 2 : 0
  138. formatStr = formatStr.replace(ret, timeSource[key].slice(beginIndex))
  139. }
  140. }
  141. return formatStr
  142. }
  143. // 日期字符串转秒级时间戳
  144. export function dateToUnix(dateText) {
  145. let times = new Date(dateText);
  146. return times.getTime() / 1000;
  147. }
  148. /**
  149. * 获取一天的时间戳
  150. * @param {String} type
  151. */
  152. export function timeFrame(type = 'start') {
  153. let timestamp = Date.parse(new Date());
  154. let date = new Date(timestamp);
  155. let Y = date.getUTCFullYear();
  156. let M = (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1)
  157. let D = date.getDate() < 10 ? '0' + date.getDate() : date.getDate();
  158. let startTime = Date.parse(Y + '/' + M + '/' + D + ' ' + '00:00:00')
  159. let endTime = Date.parse(Y + '/' + M + '/' + D + ' ' + '23:59:59')
  160. return type == 'start' ? startTime / 1000 : endTime / 1000
  161. }