util.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. import Vue from 'vue';
  2. import { isString, isObject } from 'element-ui/src/utils/types';
  3. const hasOwnProperty = Object.prototype.hasOwnProperty;
  4. export function noop() {};
  5. export function hasOwn(obj, key) {
  6. return hasOwnProperty.call(obj, key);
  7. };
  8. function extend(to, _from) {
  9. for (let key in _from) {
  10. to[key] = _from[key];
  11. }
  12. return to;
  13. };
  14. export function toObject(arr) {
  15. var res = {};
  16. for (let i = 0; i < arr.length; i++) {
  17. if (arr[i]) {
  18. extend(res, arr[i]);
  19. }
  20. }
  21. return res;
  22. };
  23. export const getValueByPath = function(object, prop) {
  24. prop = prop || '';
  25. const paths = prop.split('.');
  26. let current = object;
  27. let result = null;
  28. for (let i = 0, j = paths.length; i < j; i++) {
  29. const path = paths[i];
  30. if (!current) break;
  31. if (i === j - 1) {
  32. result = current[path];
  33. break;
  34. }
  35. current = current[path];
  36. }
  37. return result;
  38. };
  39. export function getPropByPath(obj, path, strict) {
  40. let tempObj = obj;
  41. path = path.replace(/\[(\w+)\]/g, '.$1');
  42. path = path.replace(/^\./, '');
  43. let keyArr = path.split('.');
  44. let i = 0;
  45. for (let len = keyArr.length; i < len - 1; ++i) {
  46. if (!tempObj && !strict) break;
  47. let key = keyArr[i];
  48. if (key in tempObj) {
  49. tempObj = tempObj[key];
  50. } else {
  51. if (strict) {
  52. throw new Error('please transfer a valid prop path to form item!');
  53. }
  54. break;
  55. }
  56. }
  57. return {
  58. o: tempObj,
  59. k: keyArr[i],
  60. v: tempObj ? tempObj[keyArr[i]] : null
  61. };
  62. };
  63. export const generateId = function() {
  64. return Math.floor(Math.random() * 10000);
  65. };
  66. export const valueEquals = (a, b) => {
  67. // see: https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript
  68. if (a === b) return true;
  69. if (!(a instanceof Array)) return false;
  70. if (!(b instanceof Array)) return false;
  71. if (a.length !== b.length) return false;
  72. for (let i = 0; i !== a.length; ++i) {
  73. if (a[i] !== b[i]) return false;
  74. }
  75. return true;
  76. };
  77. export const escapeRegexpString = (value = '') => String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
  78. // TODO: use native Array.find, Array.findIndex when IE support is dropped
  79. export const arrayFindIndex = function(arr, pred) {
  80. for (let i = 0; i !== arr.length; ++i) {
  81. if (pred(arr[i])) {
  82. return i;
  83. }
  84. }
  85. return -1;
  86. };
  87. export const arrayFind = function(arr, pred) {
  88. const idx = arrayFindIndex(arr, pred);
  89. return idx !== -1 ? arr[idx] : undefined;
  90. };
  91. // coerce truthy value to array
  92. export const coerceTruthyValueToArray = function(val) {
  93. if (Array.isArray(val)) {
  94. return val;
  95. } else if (val) {
  96. return [val];
  97. } else {
  98. return [];
  99. }
  100. };
  101. export const isIE = function() {
  102. return !Vue.prototype.$isServer && !isNaN(Number(document.documentMode));
  103. };
  104. export const isEdge = function() {
  105. return !Vue.prototype.$isServer && navigator.userAgent.indexOf('Edge') > -1;
  106. };
  107. export const isFirefox = function() {
  108. return !Vue.prototype.$isServer && !!window.navigator.userAgent.match(/firefox/i);
  109. };
  110. export const autoprefixer = function(style) {
  111. if (typeof style !== 'object') return style;
  112. const rules = ['transform', 'transition', 'animation'];
  113. const prefixes = ['ms-', 'webkit-'];
  114. rules.forEach(rule => {
  115. const value = style[rule];
  116. if (rule && value) {
  117. prefixes.forEach(prefix => {
  118. style[prefix + rule] = value;
  119. });
  120. }
  121. });
  122. return style;
  123. };
  124. export const kebabCase = function(str) {
  125. const hyphenateRE = /([^-])([A-Z])/g;
  126. return str
  127. .replace(hyphenateRE, '$1-$2')
  128. .replace(hyphenateRE, '$1-$2')
  129. .toLowerCase();
  130. };
  131. export const capitalize = function(str) {
  132. if (!isString(str)) return str;
  133. return str.charAt(0).toUpperCase() + str.slice(1);
  134. };
  135. export const looseEqual = function(a, b) {
  136. const isObjectA = isObject(a);
  137. const isObjectB = isObject(b);
  138. if (isObjectA && isObjectB) {
  139. return JSON.stringify(a) === JSON.stringify(b);
  140. } else if (!isObjectA && !isObjectB) {
  141. return String(a) === String(b);
  142. } else {
  143. return false;
  144. }
  145. };
  146. export const arrayEquals = function(arrayA, arrayB) {
  147. arrayA = arrayA || [];
  148. arrayB = arrayB || [];
  149. if (arrayA.length !== arrayB.length) {
  150. return false;
  151. }
  152. for (let i = 0; i < arrayA.length; i++) {
  153. if (!looseEqual(arrayA[i], arrayB[i])) {
  154. return false;
  155. }
  156. }
  157. return true;
  158. };
  159. export const isEqual = function(value1, value2) {
  160. if (Array.isArray(value1) && Array.isArray(value2)) {
  161. return arrayEquals(value1, value2);
  162. }
  163. return looseEqual(value1, value2);
  164. };
  165. export const isEmpty = function(val) {
  166. // null or undefined
  167. if (val == null) return true;
  168. if (typeof val === 'boolean') return false;
  169. if (typeof val === 'number') return !val;
  170. if (val instanceof Error) return val.message === '';
  171. switch (Object.prototype.toString.call(val)) {
  172. // String or Array
  173. case '[object String]':
  174. case '[object Array]':
  175. return !val.length;
  176. // Map or Set or File
  177. case '[object File]':
  178. case '[object Map]':
  179. case '[object Set]': {
  180. return !val.size;
  181. }
  182. // Plain Object
  183. case '[object Object]': {
  184. return !Object.keys(val).length;
  185. }
  186. }
  187. return false;
  188. };
  189. export function rafThrottle(fn) {
  190. let locked = false;
  191. return function(...args) {
  192. if (locked) return;
  193. locked = true;
  194. window.requestAnimationFrame(_ => {
  195. fn.apply(this, args);
  196. locked = false;
  197. });
  198. };
  199. }
  200. export function objToArray(obj) {
  201. if (Array.isArray(obj)) {
  202. return obj;
  203. }
  204. return isEmpty(obj) ? [] : [obj];
  205. }