utils.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. // 深拷贝,为了解决循环引用和共同引用的问题,引入了WeakMap,又因为引入WeakMap可能会导致被拷贝对象被挂上【作为WeakMap的探针的】匿名函数(是pollyfill的行为吧?),所以不会拷贝非根元素的匿名函数。
  2. function deepClone(target, hash = new WeakMap()) {
  3. // 定义一个变量
  4. let result = null
  5. // 如果当前需要深拷贝的是一个对象的话
  6. if (typeof target === 'object') {
  7. if (hash.has(target)) { // 如果是循环引用
  8. result = hash.get(target)
  9. } else if (Array.isArray(target)) { // 如果是一个数组的话
  10. result = [] // 将result赋值为一个数组,并且执行遍历
  11. hash.set(target, result)
  12. for (let i in target) {
  13. if (!(typeof(target[i]) === 'function' && !target.name)) {
  14. // 递归克隆数组中的每一项
  15. result.push(deepClone(target[i], hash))
  16. }
  17. }
  18. // 判断如果当前的值是null的话;直接赋值为null
  19. } else if (target === null) {
  20. result = null
  21. // 判断如果当前的值是一个RegExp对象的话,直接赋值
  22. } else if (target.constructor === RegExp) {
  23. result = target
  24. } else {
  25. // 否则是普通对象,直接for in循环,递归赋值对象的所有值
  26. result = {}
  27. hash.set(target, result)
  28. for (let i in target) {
  29. if (!(typeof(target[i]) === 'function' && !target.name)) {
  30. result[i] = deepClone(target[i], hash)
  31. }
  32. }
  33. }
  34. } else if (typeof target === 'function') {
  35. result = target
  36. } else { // 如果不是对象也不是函数,直接赋值
  37. result = target
  38. }
  39. // 返回最终结果
  40. return result
  41. }
  42. export default {
  43. throttle(fn, interval) {
  44. let lastRunTime = 0
  45. return function (...args) {
  46. let elapsedTime = Date.now() - lastRunTime
  47. if (elapsedTime < interval) {
  48. return null
  49. }
  50. let context = this
  51. lastRunTime = Date.now()
  52. return fn.apply(context, args)
  53. }
  54. },
  55. copyToClipBoard(content) {
  56. let tempDom = document.createElement('input')
  57. tempDom.setAttribute('value', content)
  58. document.body.appendChild(tempDom)
  59. tempDom.select()
  60. tempDom.setSelectionRange(0, 9999)
  61. document.execCommand('Copy')
  62. document.body.removeChild(tempDom)
  63. },
  64. showToast(contentStr) {
  65. const toastNode = document.createElement('div')
  66. toastNode.style.position = 'fixed'
  67. toastNode.style.left = '50%'
  68. toastNode.style.top = '50%'
  69. toastNode.style.transform = 'translate(-50%, -50%)'
  70. toastNode.style.backgroundColor = '#555'
  71. toastNode.style.borderRadius = '0.5rem'
  72. toastNode.style.padding = '1.67rem'
  73. toastNode.style.minWidth = '33vw'
  74. toastNode.style.color = '#fff'
  75. toastNode.style.fontSize = '1.67rem'
  76. toastNode.style.zIndex = globalConfig.zIndex.toast.self
  77. toastNode.style.display = 'flex'
  78. toastNode.style.flexDirection = 'column'
  79. toastNode.style.justifyContent = 'center'
  80. toastNode.style.alignItems = 'center'
  81. toastNode.innerText = contentStr
  82. document.body.appendChild(toastNode)
  83. setTimeout(() => {
  84. document.body.removeChild(toastNode)
  85. }, 1700)
  86. },
  87. randomWord(randomFlag, min, max) {
  88. //随机字符串
  89. var str = "",
  90. range = min,
  91. arr = [
  92. "0",
  93. "1",
  94. "2",
  95. "3",
  96. "4",
  97. "5",
  98. "6",
  99. "7",
  100. "8",
  101. "9",
  102. "a",
  103. "b",
  104. "c",
  105. "d",
  106. "e",
  107. "f",
  108. "g",
  109. "h",
  110. "i",
  111. "j",
  112. "k",
  113. "l",
  114. "m",
  115. "n",
  116. "o",
  117. "p",
  118. "q",
  119. "r",
  120. "s",
  121. "t",
  122. "u",
  123. "v",
  124. "w",
  125. "x",
  126. "y",
  127. "z",
  128. "A",
  129. "B",
  130. "C",
  131. "D",
  132. "E",
  133. "F",
  134. "G",
  135. "H",
  136. "I",
  137. "J",
  138. "K",
  139. "L",
  140. "M",
  141. "N",
  142. "O",
  143. "P",
  144. "Q",
  145. "R",
  146. "S",
  147. "T",
  148. "U",
  149. "V",
  150. "W",
  151. "X",
  152. "Y",
  153. "Z",
  154. ]
  155. if (randomFlag) {
  156. // 随机长度
  157. range = Math.round(Math.random() * (max - min)) + min
  158. }
  159. for (var i = 0; i < range; i++) {
  160. var pos = Math.round(Math.random() * (arr.length - 1))
  161. str += arr[pos]
  162. }
  163. return str
  164. },
  165. unique(arr) {
  166. let map = new Map()
  167. let array = new Array() // 数组用于返回结果
  168. for (let i = 0; i < arr.length; i++) {
  169. if (map.has(arr[i])) {
  170. // 如果有该key值
  171. map.set(arr[i], true)
  172. } else {
  173. map.set(arr[i], false) // 如果没有该key值
  174. array.push(arr[i])
  175. }
  176. }
  177. return array
  178. },
  179. deepClone,
  180. }
  181. /**
  182. * 如果想让注册的回调只调用一次就自动注销,在注册的回调中执行注销即可。
  183. */
  184. export class MessageCenter {
  185. constructor() {
  186. this._recorder = {}
  187. }
  188. logInvalidParam() {
  189. console.error('MessageCenter: invalid parameter.')
  190. }
  191. subscribe(message, callback) {
  192. if (typeof (message) !== 'string' || typeof (callback) !== 'function') {
  193. this.logInvalidParam()
  194. return
  195. }
  196. if (!Object.prototype.hasOwnProperty.call(this._recorder, message)) {
  197. this._recorder[message] = []
  198. }
  199. this._recorder[message].push(callback)
  200. }
  201. unsubscribe(message, callback) {
  202. if (typeof (message) !== 'string' || typeof (callback) !== 'function') {
  203. this.logInvalidParam()
  204. return
  205. }
  206. if (!Object.prototype.hasOwnProperty.call(this._recorder, message)) {
  207. const idx = this._recorder[message].indexOf(callback)
  208. if (idx !== -1) {
  209. this._recorder[message].splice(idx, 1)
  210. }
  211. }
  212. }
  213. publish(message, param) {
  214. console.log(this._recorder)
  215. if (Object.prototype.hasOwnProperty.call(this._recorder, message)) {
  216. this._recorder[message].forEach((callback) => {
  217. callback(param)
  218. })
  219. }
  220. }
  221. }