util.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /**
  2. * 格式化日期格式 (用于兼容ios Date对象)
  3. */
  4. export const formatDate = (time) => {
  5. // 将xxxx-xx-xx的时间格式,转换为 xxxx/xx/xx的格式
  6. return time.replace(/\-/g, "/");
  7. }
  8. /**
  9. * 对象转URL
  10. * @param {object} obj
  11. */
  12. export const urlEncode = (obj = {}) => {
  13. const result = []
  14. for (const key in obj) {
  15. const item = obj[key]
  16. if (!item) {
  17. continue
  18. }
  19. if (isArray(item)) {
  20. item.forEach(val => {
  21. result.push(key + '=' + val)
  22. })
  23. } else {
  24. result.push(key + '=' + item)
  25. }
  26. }
  27. return result.join('&')
  28. }
  29. /**
  30. * 遍历对象
  31. */
  32. export const objForEach = (obj, callback) => {
  33. Object.keys(obj).forEach((key) => {
  34. callback(obj[key], key)
  35. });
  36. }
  37. /**
  38. * 是否在数组内
  39. */
  40. export const inArray = (search, array) => {
  41. for (var i in array) {
  42. if (array[i] == search) return true
  43. }
  44. return false
  45. }
  46. /**
  47. * 对Date的扩展,将 Date 转化为指定格式的String
  48. * 月(Y)、月(m)、日(d)、小时(H)、分(M)、秒(S) 可以用 1-2 个占位符,
  49. * 例子:
  50. * dateFormat('YYYY-mm-dd HH:MM:SS', new Date()) ==> 2020-01-01 08:00:00
  51. */
  52. export const dateFormat = (fmt, date) => {
  53. const opt = {
  54. "Y+": date.getFullYear().toString(), // 年
  55. "m+": (date.getMonth() + 1).toString(), // 月
  56. "d+": date.getDate().toString(), // 日
  57. "H+": date.getHours().toString(), // 时
  58. "M+": date.getMinutes().toString(), // 分
  59. "S+": date.getSeconds().toString() // 秒
  60. // 有其他格式化字符需求可以继续添加,必须转化成字符串
  61. };
  62. let ret
  63. for (let k in opt) {
  64. ret = new RegExp("(" + k + ")").exec(fmt)
  65. if (ret) {
  66. fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
  67. };
  68. };
  69. return fmt
  70. }
  71. /**
  72. * 判断是否为空对象
  73. * @param {*} object 源对象
  74. */
  75. export const isEmptyObject = (object) => {
  76. return Object.keys(object).length === 0
  77. }
  78. /**
  79. * 判断是否为对象
  80. * @param {*} object
  81. */
  82. export const isObject = (object) => {
  83. return Object.prototype.toString.call(object) === '[object Object]'
  84. }
  85. /**
  86. * 判断是否为数组
  87. * @param {*} array
  88. */
  89. export const isArray = (array) => {
  90. return Object.prototype.toString.call(array) === '[object Array]'
  91. }
  92. /**
  93. * 判断是否为空
  94. * @param {*} object 源对象
  95. */
  96. export const isEmpty = (value) => {
  97. if (isArray(value)) {
  98. return value.length === 0
  99. }
  100. if (isObject(value)) {
  101. return isEmptyObject(value)
  102. }
  103. return !value
  104. }
  105. /**
  106. * 对象深拷贝
  107. * @param {*} obj 源对象
  108. */
  109. export const cloneObj = (obj) => {
  110. let newObj = isArray(obj) ? [] : {};
  111. if (typeof obj !== 'object') {
  112. return;
  113. }
  114. for (let i in obj) {
  115. newObj[i] = typeof obj[i] === 'object' ? cloneObj(obj[i]) : obj[i];
  116. }
  117. return newObj
  118. }
  119. // 节流函数
  120. // 思路: 第一次先设定一个变量true,
  121. // 第二次执行这个函数时,会判断变量是否true,
  122. // 是则返回。当第一次的定时器执行完函数最后会设定变量为flase。
  123. // 那么下次判断变量时则为flase,函数会依次运行。
  124. export function throttle(fn, delay = 100) {
  125. // 首先设定一个变量,在没有执行我们的定时器时为null
  126. var timer = null
  127. return function() {
  128. // 当我们发现这个定时器存在时,则表示定时器已经在运行中,需要返回
  129. if (timer) return
  130. timer = setTimeout(() => {
  131. fn.apply(this, arguments)
  132. timer = null
  133. }, delay)
  134. }
  135. }
  136. // 防抖函数
  137. // 首次运行时把定时器赋值给一个变量, 第二次执行时,
  138. // 如果间隔没超过定时器设定的时间则会清除掉定时器,
  139. // 重新设定定时器, 依次反复, 当我们停止下来时,
  140. // 没有执行清除定时器, 超过一定时间后触发回调函数。
  141. // 参考文档:https://segmentfault.com/q/1010000021145192
  142. export function debounce(fn, delay = 100) {
  143. let timer
  144. return function() {
  145. const that = this
  146. const _args = arguments // 存一下传入的参数
  147. if (timer) {
  148. clearTimeout(timer)
  149. }
  150. timer = setTimeout(function() {
  151. fn.apply(that, _args)
  152. }, delay)
  153. }
  154. }
  155. /**
  156. * 数组交集
  157. * @param {Array} 数组1
  158. * @param {Array} 数组2
  159. * @return {Array}
  160. */
  161. export const arrayIntersect = (array1, array2) => {
  162. return array1.filter(val => array2.indexOf(val) > -1)
  163. }
  164. /**
  165. * 获取当前客户端的rpx比值
  166. * @return {Number}
  167. */
  168. export const rpx = () => {
  169. const { windowWidth } = uni.getSystemInfoSync()
  170. // #ifdef H5
  171. // 与pages.json文件中的 rpxCalcMaxDeviceWidth参数对应, 请勿修改
  172. const rpxCalcMaxDeviceWidth = 750
  173. // 与pages.json文件中的 rpxCalcBaseDeviceWidth参数对应, 请勿修改
  174. const rpxCalcBaseDeviceWidth = 560
  175. const calcWindowWidth = windowWidth > rpxCalcMaxDeviceWidth ? rpxCalcBaseDeviceWidth : windowWidth
  176. return calcWindowWidth / 750
  177. // #endif
  178. // #ifndef H5
  179. return windowWidth / 750
  180. // #endif
  181. }
  182. /**
  183. * 获取当前客户端的rpx比值
  184. * @return {Number}
  185. */
  186. export const rpx2px = (num) => {
  187. return num * rpx()
  188. }