Package Exports
- kayran
Readme
kayran / 七零八碎工具函数合集
Installation

waitFor / 以优雅方式书写 await
Param
/**
* @param {Promise} 需要包装的Promise
* @returns {any[]} [0]为Promise.prototype.then返回的结果,[1]为Promise.prototype.catch返回的结果
*/// 示例
import { waitFor } from 'kayran'
const [res] = await waitFor(new Promise((resolve, reject) => {
resolve('res')
}))
console.log(res) // 'res'
const [, err] = await waitFor(new Promise((resolve, reject) => {
reject('err')
}))
console.log(err) // 'err'getMediaDuration / 获取音视频文件的时长
Param
/**
* @param {File|string} 音视频url或二进制文件
* @returns {Promise<number>} 时长 单位秒 四舍五入
*/// 示例
import { getMediaDuration } from 'kayran'
getMediaDuration('https://xxx.mp4')typeOf / 获取变量的精确类型
动机:原生js的typeof等类型检测手段都存在各种缺陷
Param
/**
* @param {any} 需要判断的变量
* @returns {string} 变量类型(全小写) 如string null undefined file...
*/// 示例
import { typeOf } from 'kayran'
typeOf(1) // 'number'isEllipsis / 判断dom是否触发溢出省略(text-overflow: ellipsis)
Param
/**
* @param {Element} 需要判断的元素
* @returns {boolean} 是否触发溢出省略
*/// 示例
import { isEllipsis } from 'kayran'
isEllipsis(document.querySelector('.text'))isEmpty & notEmpty / 判空 & 判非空
notEmpty() 等同于 !isEmpty()
Param
/**
* @param {any} 需要判断的变量
* @returns {boolean} 结果
*/// 示例
import { isEmpty, notEmpty } from 'kayran'
isEmpty(0) // false
isEmpty({}) // true
isEmpty([]) // truejsonToFormData / json转FormData
Param
/**
* @param {object} 需要转换的对象
* @param {(value?: any, key?: any) => any} mapFn 每个属性会执行该回调函数,返回值为新的属性值
* @returns {FormData} 转换后的FormData实例
*/// 示例
import { jsonToFormData } from 'kayran'
const formData = jsonToFormData({
a: 1
})
formData.get('a') // '1'// 绑定到FormData上,像Array.from一样使用
import { jsonToFormData } from 'kayran'
if (FormData.from === undefined) {
FormData.from = jsonToFormData
}
const formData = FormData.from({
a: '1',
b: '2'
})// mapFn示例
import { jsonToFormData } from 'kayran'
const formData = jsonToFormData({
a: 1
}, v => v + 1)
formData.get('a') // '2'::: tip
回调函数的返回值为undefined时,该元素不会被添加到FormData实例中(类似filter效果)。
:::
pickDeepBy / lodash-pickBy的递归版本
Param
/**
* @param {object} obj 原始对象
* @param {(value?: any, key?: any) => boolean} predicate 每个属性都会调用的方法
* @returns {object} 新的对象
*/// 示例
import { pickDeepBy } from 'kayran'
pickDeepBy({
a: 1,
b: NaN
}, (v, k) => ![NaN, null, undefined].includes(v))
// { a: 1 }pickDeepBy不会改变原始对象。
isSameOrigin / 判断是否同源
Param
/**
* @param {string} url 需要判断的url
* @returns {boolean}
*/// 示例
import { isSameOrigin } from 'kayran'
isSameOrigin('www.google.com')parseQueryString / 获取 url 中某个查询参数的值
Param
/**
* 获取当前url某个查询参数的值
* 支持微信公众号授权特例:授权后会重定向回来并在链接中加入一个code参数 但微信没有考虑hash路由的情况 所以获取这个code需要特殊处理
* @param {object}
* {string} key 查询参数的key 如果为空 则返回查询参数映射的对象 可以解构使用
* {string} [mode='hash'] router模式 可选值'history'/'hash'
* {boolean} del 是否在url中删除该值(删除会引发页面刷新)
* @returns {string|object} 查询参数中key对应的value / 如果key为空 则返回查询参数整个对象
*/// 示例
import { parseQueryString } from 'kayran'
const code = parseQueryString('code')
//or
const { code } = parseQueryString()注意:如果search和hash中同时包含code 如http://localhost:8080/?code=1#/?code=2 取的是search中的code 即返回1
loadLink / 动态加载link
Param
/**
* @param {string|object} src link url
* @returns {Promise}
*/// 示例
import { loadLink } from 'kayran'
await loadLink('https://cdn.bootcdn.net/ajax/libs/normalize/8.0.1/normalize.min.css')loadScript / 动态加载js
Param
/**
* @param {string|object} src 脚本url
* @returns {Promise}
*/// 示例
import { loadScript } from 'kayran'
loadScript('https://cdn.jsdelivr.net/npm/vue/dist/vue.js').then(e => {
console.log(Vue)
})loadStyle / 动态加载style
Param
/**
* @param {string|object|HTMLElement} arg style元素的innerText 或传对象指定style的各项属性 或style元素本身
* @returns {Promise<HTMLElement>}
*/// 示例
import { loadStyle } from 'kayran'
await loadStyle(`
ul {
list-style: none;
}
`)validator / 输入校验
Param
/**
* @param {string} 需要校验的内容
* @returns {string} 校验失败提示信息 如果校验通过则返回''
*/// 示例
import { validator } from 'kayran'
const { idCard } = validator
const errMsg = idCard('xxx')
if (errMsg) {
Toast(errMsg) // '格式不正确'
return
}该方法不是通过true和false来标识校验是否通过 因为错误往往需要一个友好的原因提示
// 如果仅仅想知道是否校验通过
!idCard('xxx') // true通过 false失败lng / 经度
/**
* @param {string|number} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { lng } = validatorlat / 纬度
/**
* @param {string|number} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { lat } = validatorphone / 手机
/**
* @param {string|number} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { phone } = validatoripv4
/**
* @param {string} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { ipv4 } = validatoripv6
/**
* @param {string} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { ipv6 } = validatorurl
含ipv4 不含ipv6
/**
* @param {string} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { url } = validatorbase64
/**
* @param {string} 需要判断的字符串
* @param {object}
* {string} mediaType 媒体类型,可选值参考 https://en.wikipedia.org/wiki/Data_URI_scheme
* {boolean} [scheme=true] 是否包含前缀
* @returns {boolean} 结果
*/
import { validator } from 'kayran'
const { base64 } = validator
base64(1, {
mediaType: 'image',
scheme: false
}) // falseidCard / 身份证
/**
* @param {string|number} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { idCard } = validatorpostcode / 邮编
/**
* @param {string|number} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { postcode } = validatortel / 座机
/**
* @param {string|number} 需要判断的值
* @param {object}
* {boolean} [multiple=true] 是否允许多个
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { tel } = validatoremail / 邮箱
/**
* @param {string} 需要判断的值
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { email } = validatorlen / 字符长度
/**
* @param {string} 需要判断的值
* @param {
* number |
* [number, number] |
* {
* min?: number
* max?: number
* }
* }
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { len } = validator
len('123', [1, 3])int / 整数
/**
* @param {string|number} 需要判断的值
* @param {
* string |
* {
* range?: string
* positiveSign?: boolean
* }
* }
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { int } = validator
int(0, '(0,2)')decimal / 小数
/**
* @param {string|number} 需要判断的值
* @param {
* string |
* {
* range?: string,
* decimalPlaces?: number | [number, number]
* }
* }
* @returns {string} 判断结果
*/
import { validator } from 'kayran'
const { decimal } = validator
decimal(80, '[80,+∞]')
decimal('80.1', {
decimalPlaces: [0, 1]
})getFinalProp / 获取最终prop(适用于组件开发者)
Vue提供了prop的局部配置和默认值配置,但在封装组件时,还会非常需要一个“全局配置”,否则可能导致每个组件实例进行重复的配置。
举个例子,Element 的size与zIndex就是支持全局配置的。
当配置多了以后,由于存在不同的优先级,最终组件采用的是哪一项配置,需要进行一定的判断,
在涉及到对象时,判断可能会变得相当复杂。
getFinalProp的作用就是帮助你计算出最终的配置。
Features
- 和Vue的props一样,提供是否必传、数据类型和自定义的校验
- 对于plain object类型的prop,支持深合并、浅合并和直接覆盖
- 支持将对象的键统一为驼峰命名,以避免引发某些bug
- 支持动态生成默认值
Param
/**
* @param {any[]} propSequence - prop序列(权重从高到低,最后是默认配置)
* @param {object} config - 配置
* @param {string} config.name - prop名称,用于报错提示
* @param {string|string[]} config.type - 数据类型校验
* @param {function} config.validator - 自定义校验
* @param {boolean} config.required = false - 是否必传校验
* @param {string} config.mergeObject = 'deep' - 合并对象的方式
* @param {string} config.camelCase = true - 是否将对象的键统一为驼峰命名
* @returns {any} 最终的prop
*/// 示例
import { getFinalProp } from 'kayran'
getFinalProp([1, 2, undefined]) // 1config.mergeObject
'deep': 深合并,高权重prop的对象键会覆盖低权重prop的同名键,包含嵌套的对象(默认值)'shallow': 浅合并,高权重prop的对象键会覆盖低权重prop的同名键,不含嵌套的对象false: 不合并,直接覆盖,高权重prop的对象会直接覆盖低权重prop的对象,与值类型的表现一致
config.camelCase
Vue的prop同时支持驼峰和短横线格式,如果用户同时传了同一个prop的两种格式,值还是不相同的,问题来了,此时应该取哪一个值?
在多个配置进行合并时,结果会更加难以预测,所以getFinalProp在合并对象后默认将对象的键统一为驼峰命名。
::: tip 为什么不默认使用短横线命名?
参见Vue官方风格指南
:::
怎么判断某个prop有没有传?
以该prop是否全等于undefined作为标识
动态生成默认值
使用场景:需要根据用户传的参数来决定默认值
用法:最后一个prop使用function类型,function的参数是前面所有prop的计算结果
// 示例
getFinalProp([{
a: {
a: 1
}
}, {
a: {
a: 2,
b: 1
}
}, config => ({
a: {
c: config.a.a === 1 ? 1 : null
}
})])
/**
* 将得到:
* {
* a: {
* a: 1,
* b: 1,
* c: 1
* }
* }
*/getGlobalAttrs / 获取全局attrs(适用于组件开发者)
在Vue组件中,声明过的prop可以通过 this.$props 获取,没有声明的可以通过 this.$attrs 获取,
但是全局配置就无法区分哪部分是props哪部分是attrs了。
getGlobalAttrs就是帮助你获取全局配置中的attrs的。
使用场景:二次封装组件时,往往需要使用 v-bind="$attrs" 来实现不破坏底层组件的原生能力,
getGlobalAttrs就是在此基础上提供全局配置的能力。
Param
/**
* @param {object} globalConfig - 全局配置
* @param {object} $props - this.$props(当前组件接收到的 props 对象)
* @returns {object} globalAttrs - 全局配置中的attrs部分
*/<!-- 示例 -->
<template>
<某底层组件 v-bind="Attrs"/>
</template>
<script>
import { getFinalProp, getGlobalAttrs } from 'kayran'
import globalConfig from './config'
export default {
computed: {
// Attrs即为局部与全局attrs经过权重计算得到的结果
Attrs () {
return getFinalProp([
this.$attrs,
getGlobalAttrs(globalConfig, this.$props)
])
}
}
}
</script>