nutui-uniapp
Version:
京东风格的轻量级移动端 Uniapp、Vue3 组件库(支持小程序开发)
278 lines (225 loc) • 6.97 kB
text/typescript
import { isArray, isDef, isObject } from './is'
// 变量类型判断
export function TypeOfFun(value: any) {
if (value === null)
return 'null'
const type = typeof value
if (type === 'undefined' || type === 'string')
return type
const typeString = toString.call(value)
switch (typeString) {
case '[object Array]':
return 'array'
case '[object Date]':
return 'date'
case '[object Boolean]':
return 'boolean'
case '[object Number]':
return 'number'
case '[object Function]':
return 'function'
case '[object RegExp]':
return 'regexp'
case '[object Object]':
if (undefined !== value.nodeType) {
if (value.nodeType === 3)
return /\S/.test(value.nodeValue) ? 'textnode' : 'whitespace'
else
return 'element'
}
else {
return 'object'
}
default:
return 'unknow'
}
}
//
export const objectToString = Object.prototype.toString
export const toTypeString = (value: unknown): string => objectToString.call(value)
export function toRawType(value: unknown): string {
// extract "RawType" from strings like "[object RawType]"
return toTypeString(value).slice(8, -1)
}
export const win = window
export const docu = document
export const body = docu.body
export function getPropByPath(obj: any, keyPath: string) {
try {
return keyPath.split('.').reduce((prev, curr) => prev[curr], obj)
}
// eslint-disable-next-line unused-imports/no-unused-vars
catch (error) {
return ''
}
}
export function floatData(format: any, dataOp: any, mapOps: any) {
const mergeFormat = Object.assign({}, format)
const mergeMapOps = Object.assign({}, mapOps)
if (Object.keys(dataOp).length > 0) {
Object.keys(mergeFormat).forEach((keys) => {
if (Object.prototype.hasOwnProperty.call(mergeMapOps, keys)) {
const tof = TypeOfFun(mergeMapOps[keys])
if (tof === 'function')
mergeFormat[keys] = mergeMapOps[keys](dataOp)
if (tof === 'string')
mergeFormat[keys] = dataOp[mergeMapOps[keys]]
}
else {
if (dataOp[keys])
mergeFormat[keys] = dataOp[keys]
}
})
return mergeFormat
}
return format
}
export function myFixed(num: any, digit = 2) {
if (Object.is(Number.parseFloat(num), Number.NaN))
return console.warn(`传入的值:${num}不是一个数字`)
num = Number.parseFloat(num)
return (Math.round((num + Number.EPSILON) * 10 ** digit) / 10 ** digit).toFixed(digit)
}
export function preventDefault(event: Event, isStopPropagation?: boolean) {
if (typeof event.cancelable !== 'boolean' || event.cancelable)
event.preventDefault()
if (isStopPropagation)
event.stopPropagation()
}
function cacheStringFunction<T extends (str: string) => string>(fn: T): T {
const cache: Record<string, string> = Object.create(null)
return ((str: string) => {
const hit = cache[str]
return hit || (cache[str] = fn(str))
}) as T
}
const hyphenateRE = /\B([A-Z])/g
export const hyphenate = cacheStringFunction((str: string) =>
str.replace(hyphenateRE, '-$1').toLowerCase(),
)
export function padZero(num: number | string, length = 2): string {
num += ''
while ((num as string).length < length)
num = `0${num}`
return num.toString()
}
export const clamp = (num: number, min: number, max: number): number => Math.min(Math.max(num, min), max)
export function getScrollTopRoot(): number {
return window.scrollY || document.documentElement.scrollTop || document.body.scrollTop || 0
}
type ObjectIndex = Record<string, unknown>
const { hasOwnProperty } = Object.prototype
function assignKey(to: ObjectIndex, from: ObjectIndex, key: string) {
const val = from[key]
if (!isDef(val))
return
if (!hasOwnProperty.call(to, key) || !isObject(val))
to[key] = val
else
// eslint-disable-next-line unicorn/new-for-builtins
to[key] = deepAssign(Object(to[key]), val)
}
export function deepAssign(to: ObjectIndex, from: ObjectIndex): ObjectIndex {
Object.keys(from).forEach((key) => {
assignKey(to, from, key)
})
return to
}
export function omit(obj: Record<string, unknown>, keys: string[]) {
if (Object.prototype.toString.call(obj) === '[object Object]')
return obj
return Object.keys(obj).reduce((prev, key) => {
if (!keys.includes(key))
prev[key] = obj[key]
return prev
}, {} as Record<string, unknown>)
}
export interface Deferred<T> extends Promise<T> {
resolve: (value?: T) => void
reject: (value?: any) => void
}
export function createDeferred<T>(): Deferred<T> {
let resolve: Deferred<T>['resolve'] = noop
let reject: Deferred<T>['reject'] = noop
const promise = new Promise((_resolve, _reject) => {
resolve = _resolve
reject = _reject
}) as unknown as Deferred<T>
promise.resolve = resolve
promise.reject = reject
return promise
}
export function toArray<T>(value?: T | T[]): T[] {
if (!value)
return []
return Array.isArray(value) ? value : [value]
}
export function noop() { }
export function getRandomId() {
return Math.random().toString(36).slice(-8)
}
export function isLooseEqual(a: any, b: any): boolean {
if (a === b)
return true
const isObjectA = isObject(a)
const isObjectB = isObject(b)
if (isObjectA && isObjectB)
return JSON.stringify(a) === JSON.stringify(b)
else if (!isObjectA && !isObjectB)
return String(a) === String(b)
else
return false
}
export function isEqualArray(a: any, b: any): boolean {
if (a === b)
return true
if (!isArray(a) || !isArray(b))
return false
if (a.length !== b.length)
return false
for (let i = 0; i < a.length; i++) {
if (!isLooseEqual(a[i], b[i]))
return false
}
return true
}
export function isEqualValue(a: any, b: any): boolean {
if (a === b)
return true
if (isArray(a) && isArray(b))
return isEqualArray(a, b)
return isLooseEqual(a, b)
}
export function cloneDeep<T = any>(obj: T, cache = new WeakMap()): T {
if (obj === null || typeof obj !== 'object')
return obj
if (cache.has(obj))
return cache.get(obj)
let clone
if (obj instanceof Date) {
clone = new Date(obj.getTime())
}
else if (obj instanceof RegExp) {
clone = new RegExp(obj)
}
else if (obj instanceof Map) {
clone = new Map(Array.from(obj, ([key, value]) => [key, cloneDeep(value, cache)]))
}
else if (obj instanceof Set) {
clone = new Set(Array.from(obj, value => cloneDeep(value, cache)))
}
else if (Array.isArray(obj)) {
clone = obj.map(value => cloneDeep(value, cache))
}
else if (Object.prototype.toString.call(obj) === '[object Object]') {
clone = Object.create(Object.getPrototypeOf(obj))
cache.set(obj, clone)
for (const [key, value] of Object.entries(obj))
clone[key] = cloneDeep(value, cache)
}
else {
clone = Object.assign({}, obj)
}
cache.set(obj, clone)
return clone
}