gaoluyang
3 天以前 92230c9a97dc9ce9df3313d11d26999c04bb6b26
src/uni_modules/uni-forms/components/uni-forms/utils.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,293 @@
/**
 * ç®€å•处理对象拷贝
 * @param {Obejct} è¢«æ‹·è´å¯¹è±¡
 * @@return {Object} æ‹·è´å¯¹è±¡
 */
export const deepCopy = (val) => {
   return JSON.parse(JSON.stringify(val))
}
/**
 * è¿‡æ»¤æ•°å­—类型
 * @param {String} format æ•°å­—类型
 * @@return {Boolean} è¿”回是否为数字类型
 */
export const typeFilter = (format) => {
   return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp';
}
/**
 * æŠŠ value è½¬æ¢æˆæŒ‡å®šçš„类型,用于处理初始值,原因是初始值需要入库不能为 undefined
 * @param {String} key å­—段名
 * @param {any} value å­—段值
 * @param {Object} rules è¡¨å•校验规则
 */
export const getValue = (key, value, rules) => {
   const isRuleNumType = rules.find(val => val.format && typeFilter(val.format));
   const isRuleBoolType = rules.find(val => (val.format && val.format === 'boolean') || val.format === 'bool');
   // è¾“入类型为 number
   if (!!isRuleNumType) {
      if (!value && value !== 0) {
         value = null
      } else {
         value = isNumber(Number(value)) ? Number(value) : value
      }
   }
   // è¾“入类型为 boolean
   if (!!isRuleBoolType) {
      value = isBoolean(value) ? value : false
   }
   return value;
}
/**
 * èŽ·å–è¡¨å•æ•°æ®
 * @param {String|Array} name çœŸå®žåç§°ï¼Œéœ€è¦ä½¿ç”¨ realName èŽ·å–
 * @param {Object} data åŽŸå§‹æ•°æ®
 * @param {any} value  éœ€è¦è®¾ç½®çš„值
 */
export const setDataValue = (field, formdata, value) => {
   formdata[field] = value
   return value || ''
}
/**
 * èŽ·å–è¡¨å•æ•°æ®
 * @param {String|Array} field çœŸå®žåç§°ï¼Œéœ€è¦ä½¿ç”¨ realName èŽ·å–
 * @param {Object} data åŽŸå§‹æ•°æ®
 */
export const getDataValue = (field, data) => {
   return objGet(data, field)
}
/**
 * èŽ·å–è¡¨å•ç±»åž‹
 * @param {String|Array} field çœŸå®žåç§°ï¼Œéœ€è¦ä½¿ç”¨ realName èŽ·å–
 */
export const getDataValueType = (field, data) => {
   const value = getDataValue(field, data)
   return {
      type: type(value),
      value
   }
}
/**
 * èŽ·å–è¡¨å•å¯ç”¨çš„çœŸå®žname
 * @param {String|Array} name è¡¨å•name
 * @@return {String} è¡¨å•可用的真实name
 */
export const realName = (name, data = {}) => {
   const base_name = _basePath(name)
   if (typeof base_name === 'object' && Array.isArray(base_name) && base_name.length > 1) {
      const realname = base_name.reduce((a, b) => a += `#${b}`, '_formdata_')
      return realname
   }
   return base_name[0] || name
}
/**
 * åˆ¤æ–­æ˜¯å¦è¡¨å•可用的真实name
 * @param {String|Array} name è¡¨å•name
 * @@return {String} è¡¨å•可用的真实name
 */
export const isRealName = (name) => {
   const reg = /^_formdata_#*/
   return reg.test(name)
}
/**
 * èŽ·å–è¡¨å•æ•°æ®çš„åŽŸå§‹æ ¼å¼
 * @@return {Object|Array} object éœ€è¦è§£æžçš„æ•°æ®
 */
export const rawData = (object = {}, name) => {
   let newData = JSON.parse(JSON.stringify(object))
   let formData = {}
   for(let i in newData){
      let path = name2arr(i)
      objSet(formData,path,newData[i])
   }
   return formData
}
/**
 * çœŸå®žname还原为 array
 * @param {*} name
 */
export const name2arr = (name) => {
   let field = name.replace('_formdata_#', '')
   field = field.split('#').map(v => (isNumber(v) ? Number(v) : v))
   return field
}
/**
 * å¯¹è±¡ä¸­è®¾ç½®å€¼
 * @param {Object|Array} object æºæ•°æ®
 * @param {String| Array} path 'a.b.c' æˆ– ['a',0,'b','c']
 * @param {String} value éœ€è¦è®¾ç½®çš„值
 */
export const objSet = (object, path, value) => {
   if (typeof object !== 'object') return object;
   _basePath(path).reduce((o, k, i, _) => {
      if (i === _.length - 1) {
         // è‹¥éåŽ†ç»“æŸç›´æŽ¥èµ‹å€¼
         o[k] = value
         return null
      } else if (k in o) {
         // è‹¥å­˜åœ¨å¯¹åº”路径,则返回找到的对象,进行下一次遍历
         return o[k]
      } else {
         // è‹¥ä¸å­˜åœ¨å¯¹åº”路径,则创建对应对象,若下一路径是数字,新对象赋值为空数组,否则赋值为空对象
         o[k] = /^[0-9]{1,}$/.test(_[i + 1]) ? [] : {}
         return o[k]
      }
   }, object)
   // è¿”回object
   return object;
}
// å¤„理 path, path有三种形式:'a[0].b.c'、'a.0.b.c' å’Œ ['a','0','b','c'],需要统一处理成数组,便于后续使用
function _basePath(path) {
   // è‹¥æ˜¯æ•°ç»„,则直接返回
   if (Array.isArray(path)) return path
   // è‹¥æœ‰ '[',']',则替换成将 '[' æ›¿æ¢æˆ '.',去掉 ']'
   return path.replace(/\[/g, '.').replace(/\]/g, '').split('.')
}
/**
 * ä»Žå¯¹è±¡ä¸­èŽ·å–å€¼
 * @param {Object|Array} object æºæ•°æ®
 * @param {String| Array} path 'a.b.c' æˆ– ['a',0,'b','c']
 * @param {String} defaultVal å¦‚果无法从调用链中获取值的默认值
 */
export const objGet = (object, path, defaultVal = 'undefined') => {
   // å…ˆå°†path处理成统一格式
   let newPath = _basePath(path)
   // é€’归处理,返回最后结果
   let val = newPath.reduce((o, k) => {
      return (o || {})[k]
   }, object);
   return !val || val !== undefined ? val : defaultVal
}
/**
 * æ˜¯å¦ä¸º number ç±»åž‹
 * @param {any} num éœ€è¦åˆ¤æ–­çš„值
 * @return {Boolean} æ˜¯å¦ä¸º number
 */
export const isNumber = (num) => {
   return !isNaN(Number(num))
}
/**
 * æ˜¯å¦ä¸º boolean ç±»åž‹
 * @param {any} bool éœ€è¦åˆ¤æ–­çš„值
 * @return {Boolean} æ˜¯å¦ä¸º boolean
 */
export const isBoolean = (bool) => {
   return (typeof bool === 'boolean')
}
/**
 * æ˜¯å¦æœ‰å¿…填字段
 * @param {Object} rules è§„则
 * @return {Boolean} æ˜¯å¦æœ‰å¿…填字段
 */
export const isRequiredField = (rules) => {
   let isNoField = false;
   for (let i = 0; i < rules.length; i++) {
      const ruleData = rules[i];
      if (ruleData.required) {
         isNoField = true;
         break;
      }
   }
   return isNoField;
}
/**
 * èŽ·å–æ•°æ®ç±»åž‹
 * @param {Any} obj éœ€è¦èŽ·å–æ•°æ®ç±»åž‹çš„å€¼
 */
export const type = (obj) => {
   var class2type = {};
   // ç”Ÿæˆclass2type映射
   "Boolean Number String Function Array Date RegExp Object Error".split(" ").map(function(item, index) {
      class2type["[object " + item + "]"] = item.toLowerCase();
   })
   if (obj == null) {
      return obj + "";
   }
   return typeof obj === "object" || typeof obj === "function" ?
      class2type[Object.prototype.toString.call(obj)] || "object" :
      typeof obj;
}
/**
 * åˆ¤æ–­ä¸¤ä¸ªå€¼æ˜¯å¦ç›¸ç­‰
 * @param {any} a å€¼
 * @param {any} b å€¼
 * @return {Boolean} æ˜¯å¦ç›¸ç­‰
 */
export const isEqual = (a, b) => {
   //如果a和b本来就全等
   if (a === b) {
      //判断是否为0和-0
      return a !== 0 || 1 / a === 1 / b;
   }
   //判断是否为null和undefined
   if (a == null || b == null) {
      return a === b;
   }
   //接下来判断a和b的数据类型
   var classNameA = toString.call(a),
      classNameB = toString.call(b);
   //如果数据类型不相等,则返回false
   if (classNameA !== classNameB) {
      return false;
   }
   //如果数据类型相等,再根据不同数据类型分别判断
   switch (classNameA) {
      case '[object RegExp]':
      case '[object String]':
         //进行字符串转换比较
         return '' + a === '' + b;
      case '[object Number]':
         //进行数字转换比较,判断是否为NaN
         if (+a !== +a) {
            return +b !== +b;
         }
         //判断是否为0或-0
         return +a === 0 ? 1 / +a === 1 / b : +a === +b;
      case '[object Date]':
      case '[object Boolean]':
         return +a === +b;
   }
   //如果是对象类型
   if (classNameA == '[object Object]') {
      //获取a和b的属性长度
      var propsA = Object.getOwnPropertyNames(a),
         propsB = Object.getOwnPropertyNames(b);
      if (propsA.length != propsB.length) {
         return false;
      }
      for (var i = 0; i < propsA.length; i++) {
         var propName = propsA[i];
         //如果对应属性对应值不相等,则返回false
         if (a[propName] !== b[propName]) {
            return false;
         }
      }
      return true;
   }
   //如果是数组类型
   if (classNameA == '[object Array]') {
      if (a.toString() == b.toString()) {
         return true;
      }
      return false;
   }
}