diff --git a/uni_modules/uview-ui/changelog.md b/uni_modules/uview-ui/changelog.md index f32a59d9..f7db7d0f 100644 --- a/uni_modules/uview-ui/changelog.md +++ b/uni_modules/uview-ui/changelog.md @@ -1,3 +1,10 @@ +## 2.0.25(2022-01-27) +# uView2.0重磅发布,利剑出鞘,一统江湖 + +1. 修复text组件mode=price时,可能会导致精度错误的问题 +2. 添加$u.setConfig()方法,可设置uView内置的config, props, zIndex, color属性,详见:[修改uView内置配置方案](https://uviewui.com/components/setting.html#%E9%BB%98%E8%AE%A4%E5%8D%95%E4%BD%8D%E9%85%8D%E7%BD%AE) +3. 优化form组件在errorType=toast时,如果输入错误页面会有抖动的问题 +4. 修复$u.addUnit()对配置默认单位可能无效的问题 ## 2.0.24(2022-01-25) # uView2.0重磅发布,利剑出鞘,一统江湖 diff --git a/uni_modules/uview-ui/components/u-form-item/u-form-item.vue b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue index a9bd2cae..fe58f412 100644 --- a/uni_modules/uview-ui/components/u-form-item/u-form-item.vue +++ b/uni_modules/uview-ui/components/u-form-item/u-form-item.vue @@ -69,7 +69,7 @@ diff --git a/uni_modules/uview-ui/libs/config/config.js b/uni_modules/uview-ui/libs/config/config.js index 8a60cb4c..f2a24d35 100644 --- a/uni_modules/uview-ui/libs/config/config.js +++ b/uni_modules/uview-ui/libs/config/config.js @@ -1,5 +1,5 @@ -// 此版本发布于2022-01-25 -const version = '2.0.24' +// 此版本发布于2022-01-27 +const version = '2.0.25' // 开发环境才提示,生产环境不会提示 if (process.env.NODE_ENV === 'development') { diff --git a/uni_modules/uview-ui/libs/function/index.js b/uni_modules/uview-ui/libs/function/index.js index 15f58001..b510d446 100644 --- a/uni_modules/uview-ui/libs/function/index.js +++ b/uni_modules/uview-ui/libs/function/index.js @@ -7,7 +7,7 @@ import test from './test.js' * @param {number} value */ function range(min = 0, max = 0, value = 0) { - return Math.max(min, Math.min(max, Number(value))) + return Math.max(min, Math.min(max, Number(value))) } /** @@ -17,42 +17,42 @@ function range(min = 0, max = 0, value = 0) { * @returns {number|string} */ function getPx(value, unit = false) { - if (test.number(value)) { - return unit ? `${value}px` : Number(value) - } - // 如果带有rpx,先取出其数值部分,再转为px值 - if (/(rpx|upx)$/.test(value)) { - return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value))) - } - return unit ? `${parseInt(value)}px` : parseInt(value) + if (test.number(value)) { + return unit ? `${value}px` : Number(value) + } + // 如果带有rpx,先取出其数值部分,再转为px值 + if (/(rpx|upx)$/.test(value)) { + return unit ? `${uni.upx2px(parseInt(value))}px` : Number(uni.upx2px(parseInt(value))) + } + return unit ? `${parseInt(value)}px` : parseInt(value) } /** -* @description 进行延时,以达到可以简写代码的目的 比如: await uni.$u.sleep(20)将会阻塞20ms -* @param {number} value 堵塞时间 单位ms 毫秒 -* @returns {Promise} 返回promise -*/ + * @description 进行延时,以达到可以简写代码的目的 比如: await uni.$u.sleep(20)将会阻塞20ms + * @param {number} value 堵塞时间 单位ms 毫秒 + * @returns {Promise} 返回promise + */ function sleep(value = 30) { - return new Promise((resolve) => { - setTimeout(() => { - resolve() - }, value) - }) + return new Promise((resolve) => { + setTimeout(() => { + resolve() + }, value) + }) } /** -* @description 运行期判断平台 -* @returns {string} 返回所在平台(小写) -* @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台 -*/ + * @description 运行期判断平台 + * @returns {string} 返回所在平台(小写) + * @link 运行期判断平台 https://uniapp.dcloud.io/frame?id=判断平台 + */ function os() { - return uni.getSystemInfoSync().platform.toLowerCase() + return uni.getSystemInfoSync().platform.toLowerCase() } /** -* @description 获取系统信息同步接口 -* @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync -*/ + * @description 获取系统信息同步接口 + * @link 获取系统信息同步接口 https://uniapp.dcloud.io/api/system/info?id=getsysteminfosync + */ function sys() { - return uni.getSystemInfoSync() + return uni.getSystemInfoSync() } /** @@ -61,11 +61,11 @@ function sys() { * @param {Number} max 最大值 */ function random(min, max) { - if (min >= 0 && max > 0 && max >= min) { - const gab = max - min + 1 - return Math.floor(Math.random() * gab + min) - } - return 0 + if (min >= 0 && max > 0 && max >= min) { + const gab = max - min + 1 + return Math.floor(Math.random() * gab + min) + } + return 0 } /** @@ -74,32 +74,32 @@ function random(min, max) { * @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制 */ function guid(len = 32, firstU = true, radix = null) { - const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('') - const uuid = [] - radix = radix || chars.length - - if (len) { - // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 - for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] - } else { - let r - // rfc4122标准要求返回的uuid中,某些位为固定的字符 - uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-' - uuid[14] = '4' - - for (let i = 0; i < 36; i++) { - if (!uuid[i]) { - r = 0 | Math.random() * 16 - uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r] - } - } - } - // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class - if (firstU) { - uuid.shift() - return `u${uuid.join('')}` - } - return uuid.join('') + const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('') + const uuid = [] + radix = radix || chars.length + + if (len) { + // 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位 + for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix] + } else { + let r + // rfc4122标准要求返回的uuid中,某些位为固定的字符 + uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-' + uuid[14] = '4' + + for (let i = 0; i < 36; i++) { + if (!uuid[i]) { + r = 0 | Math.random() * 16 + uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r] + } + } + } + // 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class + if (firstU) { + uuid.shift() + return `u${uuid.join('')}` + } + return uuid.join('') } /** @@ -110,18 +110,18 @@ function guid(len = 32, firstU = true, radix = null) { * @param {string|undefined} name 父组件的参数名 */ function $parent(name = undefined) { - let parent = this.$parent - // 通过while历遍,这里主要是为了H5需要多层解析的问题 - while (parent) { - // 父组件 - if (parent.$options && parent.$options.name !== name) { - // 如果组件的name不相等,继续上一级寻找 - parent = parent.$parent - } else { - return parent - } - } - return false + let parent = this.$parent + // 通过while历遍,这里主要是为了H5需要多层解析的问题 + while (parent) { + // 父组件 + if (parent.$options && parent.$options.name !== name) { + // 如果组件的name不相等,继续上一级寻找 + parent = parent.$parent + } else { + return parent + } + } + return false } /** @@ -132,37 +132,37 @@ function $parent(name = undefined) { * @returns {object|string} */ function addStyle(customStyle, target = 'object') { - // 字符串转字符串,对象转对象情形,直接返回 - if (test.empty(customStyle) || typeof (customStyle) === 'object' && target === 'object' || target === 'string' - && typeof (customStyle) === 'string') { - return customStyle - } - // 字符串转对象 - if (target === 'object') { - // 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的 - customStyle = trim(customStyle) - // 根据";"将字符串转为数组形式 - const styleArray = customStyle.split(';') - const style = {} - // 历遍数组,拼接成对象 - for (let i = 0; i < styleArray.length; i++) { - // 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤 - if (styleArray[i]) { - const item = styleArray[i].split(':') - style[trim(item[0])] = trim(item[1]) - } - } - return style - } - // 这里为对象转字符串形式 - let string = '' - for (const i in customStyle) { - // 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名 - const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() - string += `${key}:${customStyle[i]};` - } - // 去除两端空格 - return trim(string) + // 字符串转字符串,对象转对象情形,直接返回 + if (test.empty(customStyle) || typeof(customStyle) === 'object' && target === 'object' || target === 'string' && + typeof(customStyle) === 'string') { + return customStyle + } + // 字符串转对象 + if (target === 'object') { + // 去除字符串样式中的两端空格(中间的空格不能去掉,比如padding: 20px 0如果去掉了就错了),空格是无用的 + customStyle = trim(customStyle) + // 根据";"将字符串转为数组形式 + const styleArray = customStyle.split(';') + const style = {} + // 历遍数组,拼接成对象 + for (let i = 0; i < styleArray.length; i++) { + // 'font-size:20px;color:red;',如此最后字符串有";"的话,会导致styleArray最后一个元素为空字符串,这里需要过滤 + if (styleArray[i]) { + const item = styleArray[i].split(':') + style[trim(item[0])] = trim(item[1]) + } + } + return style + } + // 这里为对象转字符串形式 + let string = '' + for (const i in customStyle) { + // 驼峰转为中划线的形式,否则css内联样式,无法识别驼峰样式属性名 + const key = i.replace(/([A-Z])/g, '-$1').toLowerCase() + string += `${key}:${customStyle[i]};` + } + // 去除两端空格 + return trim(string) } /** @@ -171,9 +171,9 @@ function addStyle(customStyle, target = 'object') { * @param {string} unit 添加的单位名 比如px */ function addUnit(value = 'auto', unit = uni?.$u?.config?.unit ?? 'px') { - value = String(value) - // 用uView内置验证规则中的number判断是否为数值 - return test.number(value) ? `${value}${unit}` : value + value = String(value) + // 用uView内置验证规则中的number判断是否为数值 + return test.number(value) ? `${value}${unit}` : value } /** @@ -182,19 +182,19 @@ function addUnit(value = 'auto', unit = uni?.$u?.config?.unit ?? 'px') { * @returns {*} 克隆后的对象或者原值(不是对象) */ function deepClone(obj) { - // 对常见的“非”值,直接返回原来值 - if ([null, undefined, NaN, false].includes(obj)) return obj - if (typeof obj !== 'object' && typeof obj !== 'function') { - // 原始类型直接返回 - return obj - } - const o = test.array(obj) ? [] : {} - for (const i in obj) { - if (obj.hasOwnProperty(i)) { - o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i] - } - } - return o + // 对常见的“非”值,直接返回原来值 + if ([null, undefined, NaN, false].includes(obj)) return obj + if (typeof obj !== 'object' && typeof obj !== 'function') { + // 原始类型直接返回 + return obj + } + const o = test.array(obj) ? [] : {} + for (const i in obj) { + if (obj.hasOwnProperty(i)) { + o[i] = typeof obj[i] === 'object' ? deepClone(obj[i]) : obj[i] + } + } + return o } /** @@ -204,25 +204,25 @@ function deepClone(obj) { * @returns {object|boolean} 深度合并后的对象或者false(入参有不是对象) */ function deepMerge(target = {}, source = {}) { - target = deepClone(target) - if (typeof target !== 'object' || typeof source !== 'object') return false - for (const prop in source) { - if (!source.hasOwnProperty(prop)) continue - if (prop in target) { - if (typeof target[prop] !== 'object') { - target[prop] = source[prop] - } else if (typeof source[prop] !== 'object') { - target[prop] = source[prop] - } else if (target[prop].concat && source[prop].concat) { - target[prop] = target[prop].concat(source[prop]) - } else { - target[prop] = deepMerge(target[prop], source[prop]) - } - } else { - target[prop] = source[prop] - } - } - return target + target = deepClone(target) + if (typeof target !== 'object' || typeof source !== 'object') return false + for (const prop in source) { + if (!source.hasOwnProperty(prop)) continue + if (prop in target) { + if (typeof target[prop] !== 'object') { + target[prop] = source[prop] + } else if (typeof source[prop] !== 'object') { + target[prop] = source[prop] + } else if (target[prop].concat && source[prop].concat) { + target[prop] = target[prop].concat(source[prop]) + } else { + target[prop] = deepMerge(target[prop], source[prop]) + } + } else { + target[prop] = source[prop] + } + } + return target } /** @@ -230,10 +230,10 @@ function deepMerge(target = {}, source = {}) { * @param {*} err 错误内容 */ function error(err) { - // 开发环境才提示,生产环境不会提示 - if (process.env.NODE_ENV === 'development') { - console.error(`uView提示:${err}`) - } + // 开发环境才提示,生产环境不会提示 + if (process.env.NODE_ENV === 'development') { + console.error(`uView提示:${err}`) + } } /** @@ -242,34 +242,34 @@ function error(err) { * @returns {array} 打乱后的数组 */ function randomArray(array = []) { - // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0 - return array.sort(() => Math.random() - 0.5) + // 原理是sort排序,Math.random()产生0<= x < 1之间的数,会导致x-0.05大于或者小于0 + return array.sort(() => Math.random() - 0.5) } // padStart 的 polyfill,因为某些机型或情况,还无法支持es7的padStart,比如电脑版的微信小程序 // 所以这里做一个兼容polyfill的兼容处理 if (!String.prototype.padStart) { - // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 - String.prototype.padStart = function (maxLength, fillString = ' ') { - if (Object.prototype.toString.call(fillString) !== '[object String]') { - throw new TypeError( - 'fillString must be String' - ) - } - const str = this - // 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉 - if (str.length >= maxLength) return String(str) - - const fillLength = maxLength - str.length - let times = Math.ceil(fillLength / fillString.length) - while (times >>= 1) { - fillString += fillString - if (times === 1) { - fillString += fillString - } - } - return fillString.slice(0, fillLength) + str - } + // 为了方便表示这里 fillString 用了ES6 的默认参数,不影响理解 + String.prototype.padStart = function(maxLength, fillString = ' ') { + if (Object.prototype.toString.call(fillString) !== '[object String]') { + throw new TypeError( + 'fillString must be String' + ) + } + const str = this + // 返回 String(str) 这里是为了使返回的值是字符串字面量,在控制台中更符合直觉 + if (str.length >= maxLength) return String(str) + + const fillLength = maxLength - str.length + let times = Math.ceil(fillLength / fillString.length) + while (times >>= 1) { + fillString += fillString + if (times === 1) { + fillString += fillString + } + } + return fillString.slice(0, fillLength) + str + } } /** @@ -279,28 +279,28 @@ if (!String.prototype.padStart) { * @returns {string} 返回格式化后的字符串 */ function timeFormat(dateTime = null, fmt = 'yyyy-mm-dd') { - // 如果为null,则格式化当前时间 - if (!dateTime) dateTime = Number(new Date()) - // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 - if (dateTime.toString().length == 10) dateTime *= 1000 - const date = new Date(dateTime) - let ret - const opt = { - 'y+': date.getFullYear().toString(), // 年 - 'm+': (date.getMonth() + 1).toString(), // 月 - 'd+': date.getDate().toString(), // 日 - 'h+': date.getHours().toString(), // 时 - 'M+': date.getMinutes().toString(), // 分 - 's+': date.getSeconds().toString() // 秒 - // 有其他格式化字符需求可以继续添加,必须转化成字符串 - } - for (const k in opt) { - ret = new RegExp(`(${k})`).exec(fmt) - if (ret) { - fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0'))) - } - } - return fmt + // 如果为null,则格式化当前时间 + if (!dateTime) dateTime = Number(new Date()) + // 如果dateTime长度为10或者13,则为秒和毫秒的时间戳,如果超过13位,则为其他的时间格式 + if (dateTime.toString().length == 10) dateTime *= 1000 + const date = new Date(dateTime) + let ret + const opt = { + 'y+': date.getFullYear().toString(), // 年 + 'm+': (date.getMonth() + 1).toString(), // 月 + 'd+': date.getDate().toString(), // 日 + 'h+': date.getHours().toString(), // 时 + 'M+': date.getMinutes().toString(), // 分 + 's+': date.getSeconds().toString() // 秒 + // 有其他格式化字符需求可以继续添加,必须转化成字符串 + } + for (const k in opt) { + ret = new RegExp(`(${k})`).exec(fmt) + if (ret) { + fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0'))) + } + } + return fmt } /** @@ -312,40 +312,40 @@ function timeFormat(dateTime = null, fmt = 'yyyy-mm-dd') { * @returns {string} 转化后的内容 */ function timeFrom(timestamp = null, format = 'yyyy-mm-dd') { - if (timestamp == null) timestamp = Number(new Date()) - timestamp = parseInt(timestamp) - // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位) - if (timestamp.toString().length == 10) timestamp *= 1000 - let timer = (new Date()).getTime() - timestamp - timer = parseInt(timer / 1000) - // 如果小于5分钟,则返回"刚刚",其他以此类推 - let tips = '' - switch (true) { - case timer < 300: - tips = '刚刚' - break - case timer >= 300 && timer < 3600: - tips = `${parseInt(timer / 60)}分钟前` - break - case timer >= 3600 && timer < 86400: - tips = `${parseInt(timer / 3600)}小时前` - break - case timer >= 86400 && timer < 2592000: - tips = `${parseInt(timer / 86400)}天前` - break - default: - // 如果format为false,则无论什么时间戳,都显示xx之前 - if (format === false) { - if (timer >= 2592000 && timer < 365 * 86400) { - tips = `${parseInt(timer / (86400 * 30))}个月前` - } else { - tips = `${parseInt(timer / (86400 * 365))}年前` - } - } else { - tips = timeFormat(timestamp, format) - } - } - return tips + if (timestamp == null) timestamp = Number(new Date()) + timestamp = parseInt(timestamp) + // 判断用户输入的时间戳是秒还是毫秒,一般前端js获取的时间戳是毫秒(13位),后端传过来的为秒(10位) + if (timestamp.toString().length == 10) timestamp *= 1000 + let timer = (new Date()).getTime() - timestamp + timer = parseInt(timer / 1000) + // 如果小于5分钟,则返回"刚刚",其他以此类推 + let tips = '' + switch (true) { + case timer < 300: + tips = '刚刚' + break + case timer >= 300 && timer < 3600: + tips = `${parseInt(timer / 60)}分钟前` + break + case timer >= 3600 && timer < 86400: + tips = `${parseInt(timer / 3600)}小时前` + break + case timer >= 86400 && timer < 2592000: + tips = `${parseInt(timer / 86400)}天前` + break + default: + // 如果format为false,则无论什么时间戳,都显示xx之前 + if (format === false) { + if (timer >= 2592000 && timer < 365 * 86400) { + tips = `${parseInt(timer / (86400 * 30))}个月前` + } else { + tips = `${parseInt(timer / (86400 * 365))}年前` + } + } else { + tips = timeFormat(timestamp, format) + } + } + return tips } /** @@ -354,17 +354,20 @@ function timeFrom(timestamp = null, format = 'yyyy-mm-dd') { * @param String pos both(左右)|left|right|all 默认both */ function trim(str, pos = 'both') { - str = String(str) - if (pos == 'both') { - return str.replace(/^\s+|\s+$/g, '') - } if (pos == 'left') { - return str.replace(/^\s*/, '') - } if (pos == 'right') { - return str.replace(/(\s*$)/g, '') - } if (pos == 'all') { - return str.replace(/\s+/g, '') - } - return str + str = String(str) + if (pos == 'both') { + return str.replace(/^\s+|\s+$/g, '') + } + if (pos == 'left') { + return str.replace(/^\s*/, '') + } + if (pos == 'right') { + return str.replace(/(\s*$)/g, '') + } + if (pos == 'all') { + return str.replace(/\s+/g, '') + } + return str } /** @@ -374,55 +377,55 @@ function trim(str, pos = 'both') { * @param {string} arrayFormat 规则 indices|brackets|repeat|comma */ function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') { - const prefix = isPrefix ? '?' : '' - const _result = [] - if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets' - for (const key in data) { - const value = data[key] - // 去掉为空的参数 - if (['', undefined, null].indexOf(value) >= 0) { - continue - } - // 如果值为数组,另行处理 - if (value.constructor === Array) { - // e.g. {ids: [1, 2, 3]} - switch (arrayFormat) { - case 'indices': - // 结果: ids[0]=1&ids[1]=2&ids[2]=3 - for (let i = 0; i < value.length; i++) { - _result.push(`${key}[${i}]=${value[i]}`) - } - break - case 'brackets': - // 结果: ids[]=1&ids[]=2&ids[]=3 - value.forEach((_value) => { - _result.push(`${key}[]=${_value}`) - }) - break - case 'repeat': - // 结果: ids=1&ids=2&ids=3 - value.forEach((_value) => { - _result.push(`${key}=${_value}`) - }) - break - case 'comma': - // 结果: ids=1,2,3 - let commaStr = '' - value.forEach((_value) => { - commaStr += (commaStr ? ',' : '') + _value - }) - _result.push(`${key}=${commaStr}`) - break - default: - value.forEach((_value) => { - _result.push(`${key}[]=${_value}`) - }) - } - } else { - _result.push(`${key}=${value}`) - } - } - return _result.length ? prefix + _result.join('&') : '' + const prefix = isPrefix ? '?' : '' + const _result = [] + if (['indices', 'brackets', 'repeat', 'comma'].indexOf(arrayFormat) == -1) arrayFormat = 'brackets' + for (const key in data) { + const value = data[key] + // 去掉为空的参数 + if (['', undefined, null].indexOf(value) >= 0) { + continue + } + // 如果值为数组,另行处理 + if (value.constructor === Array) { + // e.g. {ids: [1, 2, 3]} + switch (arrayFormat) { + case 'indices': + // 结果: ids[0]=1&ids[1]=2&ids[2]=3 + for (let i = 0; i < value.length; i++) { + _result.push(`${key}[${i}]=${value[i]}`) + } + break + case 'brackets': + // 结果: ids[]=1&ids[]=2&ids[]=3 + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + break + case 'repeat': + // 结果: ids=1&ids=2&ids=3 + value.forEach((_value) => { + _result.push(`${key}=${_value}`) + }) + break + case 'comma': + // 结果: ids=1,2,3 + let commaStr = '' + value.forEach((_value) => { + commaStr += (commaStr ? ',' : '') + _value + }) + _result.push(`${key}=${commaStr}`) + break + default: + value.forEach((_value) => { + _result.push(`${key}[]=${_value}`) + }) + } + } else { + _result.push(`${key}=${value}`) + } + } + return _result.length ? prefix + _result.join('&') : '' } /** @@ -431,11 +434,11 @@ function queryParams(data = {}, isPrefix = true, arrayFormat = 'brackets') { * @param {Number} duration 提示的延迟时间,单位毫秒,默认:2000 */ function toast(title, duration = 2000) { - uni.showToast({ - title: String(title), - icon: 'none', - duration - }) + uni.showToast({ + title: String(title), + icon: 'none', + duration + }) } /** @@ -444,65 +447,65 @@ function toast(title, duration = 2000) { * @param {boolean} fill 是否使用fill填充实体的图标 */ function type2icon(type = 'success', fill = false) { - // 如果非预置值,默认为success - if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success' - let iconName = '' - // 目前(2019-12-12),info和primary使用同一个图标 - switch (type) { - case 'primary': - iconName = 'info-circle' - break - case 'info': - iconName = 'info-circle' - break - case 'error': - iconName = 'close-circle' - break - case 'warning': - iconName = 'error-circle' - break - case 'success': - iconName = 'checkmark-circle' - break - default: - iconName = 'checkmark-circle' - } - // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 - if (fill) iconName += '-fill' - return iconName + // 如果非预置值,默认为success + if (['primary', 'info', 'error', 'warning', 'success'].indexOf(type) == -1) type = 'success' + let iconName = '' + // 目前(2019-12-12),info和primary使用同一个图标 + switch (type) { + case 'primary': + iconName = 'info-circle' + break + case 'info': + iconName = 'info-circle' + break + case 'error': + iconName = 'close-circle' + break + case 'warning': + iconName = 'error-circle' + break + case 'success': + iconName = 'checkmark-circle' + break + default: + iconName = 'checkmark-circle' + } + // 是否是实体类型,加上-fill,在icon组件库中,实体的类名是后面加-fill的 + if (fill) iconName += '-fill' + return iconName } /** -* @description 数字格式化 -* @param {number|string} number 要格式化的数字 -* @param {number} decimals 保留几位小数 -* @param {string} decimalPoint 小数点符号 -* @param {string} thousandsSeparator 千分位符号 -* @returns {string} 格式化后的数字 -*/ + * @description 数字格式化 + * @param {number|string} number 要格式化的数字 + * @param {number} decimals 保留几位小数 + * @param {string} decimalPoint 小数点符号 + * @param {string} thousandsSeparator 千分位符号 + * @returns {string} 格式化后的数字 + */ function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparator = ',') { - number = (`${number}`).replace(/[^0-9+-Ee.]/g, '') - const n = !isFinite(+number) ? 0 : +number - const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) - const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator - const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint - let s = '' - const toFixedFix = function (n, prec) { - const k = 10 ** prec - return `${Math.ceil(n * k) / k}` - } - - s = (prec ? toFixedFix(n, prec) : `${Math.round(n)}`).split('.') - const re = /(-?\d+)(\d{3})/ - while (re.test(s[0])) { - s[0] = s[0].replace(re, `$1${sep}$2`) - } - - if ((s[1] || '').length < prec) { - s[1] = s[1] || '' - s[1] += new Array(prec - s[1].length + 1).join('0') - } - return s.join(dec) + number = (`${number}`).replace(/[^0-9+-Ee.]/g, '') + const n = !isFinite(+number) ? 0 : +number + const prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) + const sep = (typeof thousandsSeparator === 'undefined') ? ',' : thousandsSeparator + const dec = (typeof decimalPoint === 'undefined') ? '.' : decimalPoint + let s = '' + const toFixedFix = function(n, prec) { + const k = 10 ** prec + return `${Math.ceil(parseInt(n * k)) / k}` + } + + s = (prec ? toFixedFix(n, prec) : `${Math.round(n)}`).split('.') + const re = /(-?\d+)(\d{3})/ + while (re.test(s[0])) { + s[0] = s[0].replace(re, `$1${sep}$2`) + } + + if ((s[1] || '').length < prec) { + s[1] = s[1] || '' + s[1] += new Array(prec - s[1].length + 1).join('0') + } + return s.join(dec) } /** @@ -514,14 +517,14 @@ function priceFormat(number, decimals = 0, decimalPoint = '.', thousandsSeparato * @return {string|number} */ function getDuration(value, unit = true) { - const valueNum = parseInt(value) - if (unit) { - if (/s$/.test(value)) return value - return value > 30 ? `${value}ms` : `${value}s` - } - if (/ms$/.test(value)) return valueNum - if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000 - return valueNum + const valueNum = parseInt(value) + if (unit) { + if (/s$/.test(value)) return value + return value > 30 ? `${value}ms` : `${value}s` + } + if (/ms$/.test(value)) return valueNum + if (/s$/.test(value)) return valueNum > 30 ? valueNum : valueNum * 1000 + return valueNum } /** @@ -529,7 +532,7 @@ function getDuration(value, unit = true) { * @param {String} value 需要补零的值 */ function padZero(value) { - return `00${value}`.slice(-2) + return `00${value}`.slice(-2) } /** @@ -538,13 +541,13 @@ function padZero(value) { * @param {*} event */ function formValidate(instance, event) { - const formItem = uni.$u.$parent.call(instance, 'u-form-item') - const form = uni.$u.$parent.call(instance, 'u-form') - // 如果发生变化的input或者textarea等,其父组件中有u-form-item或者u-form等,就执行form的validate方法 - // 同时将form-item的pros传递给form,让其进行精确对象验证 - if (formItem && form) { - form.validateField(formItem.prop, () => { }, event) - } + const formItem = uni.$u.$parent.call(instance, 'u-form-item') + const form = uni.$u.$parent.call(instance, 'u-form') + // 如果发生变化的input或者textarea等,其父组件中有u-form-item或者u-form等,就执行form的validate方法 + // 同时将form-item的pros传递给form,让其进行精确对象验证 + if (formItem && form) { + form.validateField(formItem.prop, () => {}, event) + } } /** @@ -554,23 +557,24 @@ function formValidate(instance, event) { * @returns {*} */ function getProperty(obj, key) { - if (!obj) { - return - } - if (typeof key !== 'string' || key === '') { - return '' - } if (key.indexOf('.') !== -1) { - const keys = key.split('.') - let firstObj = obj[keys[0]] || {} - - for (let i = 1; i < keys.length; i++) { - if (firstObj) { - firstObj = firstObj[keys[i]] - } - } - return firstObj - } - return obj[key] + if (!obj) { + return + } + if (typeof key !== 'string' || key === '') { + return '' + } + if (key.indexOf('.') !== -1) { + const keys = key.split('.') + let firstObj = obj[keys[0]] || {} + + for (let i = 1; i < keys.length; i++) { + if (firstObj) { + firstObj = firstObj[keys[i]] + } + } + return firstObj + } + return obj[key] } /** @@ -580,82 +584,105 @@ function getProperty(obj, key) { * @param {string} value 设置的值 */ function setProperty(obj, key, value) { - if (!obj) { - return - } - // 递归赋值 - const inFn = function (_obj, keys, v) { - // 最后一个属性key - if (keys.length === 1) { - _obj[keys[0]] = v - return - } - // 0~length-1个key - while (keys.length > 1) { - const k = keys[0] - if (!_obj[k] || (typeof _obj[k] !== 'object')) { - _obj[k] = {} - } - const key = keys.shift() - // 自调用判断是否存在属性,不存在则自动创建对象 - inFn(_obj[k], keys, v) - } - } - - if (typeof key !== 'string' || key === '') { - - } else if (key.indexOf('.') !== -1) { // 支持多层级赋值操作 - const keys = key.split('.') - inFn(obj, keys, value) - } else { - obj[key] = value - } + if (!obj) { + return + } + // 递归赋值 + const inFn = function(_obj, keys, v) { + // 最后一个属性key + if (keys.length === 1) { + _obj[keys[0]] = v + return + } + // 0~length-1个key + while (keys.length > 1) { + const k = keys[0] + if (!_obj[k] || (typeof _obj[k] !== 'object')) { + _obj[k] = {} + } + const key = keys.shift() + // 自调用判断是否存在属性,不存在则自动创建对象 + inFn(_obj[k], keys, v) + } + } + + if (typeof key !== 'string' || key === '') { + + } else if (key.indexOf('.') !== -1) { // 支持多层级赋值操作 + const keys = key.split('.') + inFn(obj, keys, value) + } else { + obj[key] = value + } } /** * @description 获取当前页面路径 */ function page() { - const pages = getCurrentPages() - // 某些特殊情况下(比如页面进行redirectTo时的一些时机),pages可能为空数组 - return `/${pages[pages.length - 1]?.route ?? ''}` + const pages = getCurrentPages() + // 某些特殊情况下(比如页面进行redirectTo时的一些时机),pages可能为空数组 + return `/${pages[pages.length - 1]?.route ?? ''}` } /** * @description 获取当前路由栈实例数组 */ function pages() { - const pages = getCurrentPages() - return pages + const pages = getCurrentPages() + return pages +} + +/** + * @description 修改uView内置属性值 + * @param {object} props 修改内置props属性 + * @param {object} config 修改内置config属性 + * @param {object} color 修改内置color属性 + * @param {object} zIndex 修改内置zIndex属性 + */ +function setConfig({ + props = {}, + config = {}, + color = {}, + zIndex = {} +}) { + const { + deepMerge, + } = uni.$u + uni.$u.config = deepMerge(uni.$u.config, config) + uni.$u.props = deepMerge(uni.$u.props, props) + uni.$u.color = deepMerge(uni.$u.color, color) + uni.$u.zIndex = deepMerge(uni.$u.zIndex, zIndex) } export default { - range, - getPx, - sleep, - os, - sys, - random, - guid, - $parent, - addStyle, - addUnit, - deepClone, - deepMerge, - error, - randomArray, - timeFormat, - timeFrom, - trim, - queryParams, - toast, - type2icon, - priceFormat, - getDuration, - padZero, - formValidate, - getProperty, - setProperty, - page, - pages -} \ No newline at end of file + range, + getPx, + sleep, + os, + sys, + random, + guid, + $parent, + addStyle, + addUnit, + deepClone, + deepMerge, + error, + randomArray, + timeFormat, + timeFrom, + trim, + queryParams, + toast, + type2icon, + priceFormat, + getDuration, + padZero, + formValidate, + getProperty, + setProperty, + page, + pages, + setConfig +} diff --git a/uni_modules/uview-ui/package.json b/uni_modules/uview-ui/package.json index 4e156879..dfbde291 100644 --- a/uni_modules/uview-ui/package.json +++ b/uni_modules/uview-ui/package.json @@ -2,7 +2,7 @@ "id": "uview-ui", "name": "uview-ui", "displayName": "uView2.0重磅发布,利剑出鞘,一统江湖", - "version": "2.0.24", + "version": "2.0.25", "description": "uView UI已完美兼容nvue,全面的组件和便捷的工具会让您信手拈来,如鱼得水", "keywords": [ "uview",