数据操作
快速使用
<template>
<div>
<div>原始数据: {{ rawData }}</div>
<div>omit数据: {{ data }}</div>
</div>
</template>
<script lang="ts" setup>
import { omit } from '@cat-kit/fe'
const rawData = { id: 1, name: '张三', age: 20 }
const data = omit(rawData, ['id'])
</script>
通用操作
提供了一些各个数据类型公用的方法
isEmpty
判断一个值是否为空值, 其中0和false会被视作空值. 通常判断对象或者数组尤其是对象使用此方法.
<template>
<div>
<div v-for="value of values">
值 {{ value }} <template v-if="!isEmpty(value)">不</template>为空
</div>
</div>
</template>
<script lang="ts" setup>
import { isEmpty } from '@cat-kit/fe'
const values = [
{}, { name: '张三' }, [], 0, 1, false, true
]
</script>
getChainValue
通过一个字符串属性链来获取一个嵌套的对象的值
<template>
{{ getChainValue({ person: { name: '张三' } }, 'person.name') }}
</template>
<script lang="ts" setup>
import { getChainValue } from '@cat-kit/fe'
</script>
oneOf
判断是否为给定值中的一种
<template>
<div>
{{ oneOf(1, [1, 2]) }}
{{ oneOf(1, [2, 3]) }}
</div>
</template>
<script lang="ts" setup>
import { oneOf } from '@cat-kit/fe'
</script>
equal
判断两个值的结构是否"相等".
通常用来判断对象和数组是否在结构上相等, 也可使用第三个参数通过比较相同属性来确定相等.
比如从服务器过来的对象总是和你程序的对象不相等, 而我们可以通过约定的结构或者属性标识来确定其是否相等, 在与后端对接时, 该方法或许会很有用.
<template>
<div>
<div>a和b结构是否相等: {{ equal(a, b) }}</div>
<div>c和d结构是否相等: {{ equal(c, d) }}</div>
<div>c和d的id是否相等: {{ equal(c, d, 'id') }}</div>
</div>
</template>
<script lang="ts" setup>
import { equal } from '@cat-kit/fe'
let a = { name: '张三' }
let b = { name: '张三' }
let c = { name: '张三', id: '1' }
let d = { name: '张三', id: '1', age: 20 }
</script>
DANGER
你不能够用它来判断两个值是否相等!
错误用法
if (equal(1, 3)) {
console.log('相等')
}
正确用法
let a = { name: '张三' }
let b = { name: '张三' }
if (equal(a, b)) {
console.log('或许是同一个人')
}
deepCopy
深拷贝, 此函数能够深拷贝数组, 对象, 函数, 日期这四种常用的引用类型
<template>
<div>
<div>person: {{ person }}</div>
<div>result: {{ result }}</div>
<div>person和result是否相等: {{ person === result }}</div>
<div>person.school === result.school: {{ person.school === result.school }}</div>
</div>
</template>
<script lang="ts" setup>
import { deepCopy } from '@cat-kit/fe'
const person = { name: '张三', school: { name: '清华大学' } }
const result = deepCopy(person)
</script>
merge
合并对象. 合并的策略是会比较每个相同属性的类型, 类型不一致直接覆盖最后被合并进来的对象, 类型一致时, 如果是直接类型直接覆盖, 如果是对象或数组则直接递归合并.
<template>
{{ merge({ name: '张三' }, { name: '李四', age: 20 }) }}
</template>
<script lang="ts" setup>
import { merge } from '@cat-kit/fe'
</script>
serialize & deserialize 对象序列化 & 反序列化为对象
对象序列化: 将对象转化为可传输的字符串
反序列化: 将字符串转化为对象
<template>
<div>
<div>序列化data1: {{ serialize(data1) }}</div>
<div>序列化data2: {{ serialize(data2) }}</div>
<div>反序列化a=1: {{ deserialize('a=1') }}</div>
<div>反序列化a="1": {{ deserialize('a="1"') }}</div>
</div>
</template>
<script lang="ts" setup>
import { serialize, deserialize } from '@cat-kit/fe'
const data1 = { a: 1 }
const data2 = { a: '1' }
</script>
array 操作
提供常用的数组操作
last
直接获取数组最后一个元素
last([1, 2, 3])
// return 3
union
合并多个数组,并去重(简单类型)
union([1, 2], [2, 3], [3, 4])
//return [1, 2, 3, 4]
unionBy
合并多个数组,并按照指定字段进行去重
unionBy(
'name',
[
{ name: '张三', score: 78 },
{ name: '李四', score: 65 }
],
[
{ name: '王五', score: 82 },
{ name: '李四', score: 65 }
]
)
//return [{ name: '张三', score: 78 },{ name: '李四', score: 65 },{ name: '王五', score: 82 }]
omitArr
丢弃指定索引的数组
omitArr([1, 2, 3], 1)
// return [1, 3]
omit([1, 2, 3], [0, 2])
// return [2]
移动元素
将数组中的某个元素移动到新的位置
// 将第一个元素移动到第三个位置, 同时重新排序
arr([1, 2, 3, 4, 5, 6]).move(1, 3)
// [1, 3, 4, 2, 5, 6]
object 操作
提供常用的对象操作
omit
丢弃对象的某些属性, 并根据剩余属性生成一个新的对象
omit({ name: '张三', age: 20, id: 1 }, ['id'])
// return { name: '张三', age: 20 }
pick
选取对象的某些属性, 并根选取的属性生成一个新的对象
pick({ name: '张三', age: 20, id: 1 }, ['id'])
// return { id: 1 }
objMap
对象的映射
objMap({ a: 1, b: 2 }, v => v * 2)
// return { a: 2, b: 4 }
objEach
对象的遍历
objEach({ a: 1, b: 2 }, (v, k) => console.log(`${k}: ${v}`))
// log a: 1
// log b: 2
extend
对象继承
extend({ name: '张三', age: 10 }, { name: '李四', age: 21 }, { name: '王五' })
// return { name: '王五', age: 21 }
包装器
对象包装器,使用会更加地符合直觉, 所有的对象操作, 在对象包装器中都有对应的实现。
import { obj } from 'cat-kit'
obj({ name: '张三', age: 10 }).pick(['name'])
// return { name: '张三' }
obj({ name: '李四', age: 20 }).omit(['name'])
// return { age: 20 }
数字操作
数字操作通常用来恢复精度, 转化不同的使用方式(比如货币, 使用货币时会被转化为字符串, 并用分隔符分割千分位)
cat-kit 中提供了一个包装函数n来包裹数字.
小数精确
<template>
<div class="wrap">
<div class="title">保留小数位数</div>
<div>
<input style="width: 100px" type="text" v-model.number="fixedNum" />
保留
<input style="width: 100px" type="text" v-model.number="precision" />
</div>
<div class="sub-title">原生JS</div>
<div class="result">结果: {{ fixedNum.toFixed(precision) }}</div>
<div class="sub-title">n(num).fixed()方法</div>
<div class="result">结果: {{ n(fixedNum).fixed(precision) }}</div>
<div class="sub-title">n(num).fixed()方法(指定最大精度)</div>
<div class="result">
结果: {{ n(fixedNum).fixed({ maxPrecision: precision }) }}
</div>
<div class="sub-title">n(num).fixed()方法(指定最小精度)</div>
<div class="result">
结果: {{ n(fixedNum).fixed({ minPrecision: precision }) }}
</div>
</div>
</template>
<script lang="ts" setup>
import { n } from '@cat-kit/fe'
import { ref } from 'vue'
const fixedNum = ref(1.255)
const precision = ref(2)
</script>
<style scoped>
.wrap {
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 8px;
padding: 4px;
}
.title {
color: #333;
}
.sub-title {
color: #666;
font-size: 14px;
line-height: 1;
margin-top: 4px;
}
.result {
color: #f00;
font-size: 14px;
}
.ele {
margin-top: 12px;
}
</style>
数字计算
函数n提供了4个用于计算的静态属性:
- n.plus 加
- n.minus 减
- n.mul 乘
- n.div 除
<template>
<div class="wrap">
<div class="title">精确计算</div>
<div class="ele">
<input style="width: 100px" type="text" v-model.number="plusNum1" />
+
<input style="width: 100px" type="text" v-model.number="plusNum2" />
</div>
<div class="sub-title">原生JS</div>
<div class="result">结果: {{ plusNum1 + plusNum2 }}</div>
<div class="sub-title">n.plus()方法</div>
<div class="result">结果: {{ n.plus(plusNum1, plusNum2) }}</div>
<div class="ele">
<input style="width: 100px" type="text" v-model.number="minusNum1" />
-
<input style="width: 100px" type="text" v-model.number="minusNum2" />
</div>
<div class="sub-title">原生JS</div>
<div class="result">结果: {{ minusNum1 - minusNum2 }}</div>
<div class="sub-title">n.minus()方法</div>
<div class="result">结果: {{ n.minus(minusNum1, minusNum2) }}</div>
<div class="ele">
<input style="width: 100px" type="text" v-model.number="mulNum1" />
*
<input style="width: 100px" type="text" v-model.number="mulNum2" />
</div>
<div class="sub-title">原生JS</div>
<div class="result">结果: {{ mulNum1 * mulNum2 }}</div>
<div class="sub-title">n.mul()方法</div>
<div class="result">结果: {{ n.mul(mulNum1, mulNum2) }}</div>
<div class="ele">
<input style="width: 100px" type="text" v-model.number="divNum1" />
/
<input style="width: 100px" type="text" v-model.number="divNum2" />
</div>
<div class="sub-title">原生JS</div>
<div class="result">结果: {{ divNum1 / divNum2 }}</div>
<div class="sub-title">n.div()方法</div>
<div class="result">结果: {{ n.div(divNum1, divNum2) }}</div>
</div>
</template>
<script lang="ts" setup>
import { n } from '@cat-kit/fe'
import { ref } from 'vue'
const plusNum1 = ref(0.1)
const plusNum2 = ref(0.2)
const minusNum1 = ref(0.3)
const minusNum2 = ref(0.2)
const mulNum1 = ref(1.255)
const mulNum2 = ref(100)
const divNum1 = ref(2.1)
const divNum2 = ref(10)
</script>
<style scoped>
.wrap {
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 8px;
padding: 4px;
}
.title {
color: #333;
}
.sub-title {
color: #666;
font-size: 14px;
line-height: 1;
margin-top: 4px;
}
.result {
color: #f00;
font-size: 14px;
}
.ele {
margin-top: 12px;
}
</style>
遍历
使用n(n: number).each进行数字遍历。
n(3).each(v => {
console.log(v)
})
//log 1,2,3
货币
使用n(n: number).currency()进行数字货币化。
<template>
<div class="wrap">
<div class="title">货币</div>
<div>
<input type="text" v-model.number="currencyNum" />
保留
<input style="width: 100px" type="text" v-model.number="precision" />
</div>
<div class="sub-title">人民币</div>
<div class="result">
结果: {{ n(currencyNum).currency('CNY', precision) }}
</div>
<div class="sub-title">人民币大写</div>
<div class="result">
结果: {{ n(currencyNum).currency('CNY_HAN', precision) }}
</div>
</div>
</template>
<script lang="ts" setup>
import { n } from '@cat-kit/fe'
import { ref } from 'vue'
const precision = ref(2)
const currencyNum = ref(-123456.23)
</script>
<style scoped>
.wrap {
margin-bottom: 10px;
border: 1px solid #ccc;
border-radius: 8px;
padding: 4px;
}
.title {
color: #333;
}
.sub-title {
color: #666;
font-size: 14px;
line-height: 1;
margin-top: 4px;
}
.result {
color: #f00;
font-size: 14px;
}
.ele {
margin-top: 12px;
}
</style>
字符串操作
kebabCase 大小驼峰转kebab-case
import { str } from 'cat-kit/fe'
// import { str } from 'cat-kit/be' node.js
str('aaBbCc').kebabCase()
// 返回aa-bb-cc
str('AaBbCc').kebabCase()
// 返回aa-bb-cc
camelCase kebab-case转大小驼峰
import { str } from 'cat-kit/fe'
// import { str } from 'cat-kit/be' node.js
str('aa-bb-cc').camelCase()
// 返回aaBbCc
str('aa-bb-cc').camelCase('lower')
// 返回aaBbCc
str('aa-bb-cc').camelCase('upper')
// 返回AaBbCc
joinPath路径拼接
路径通常用于路由, url之类的拼接, 解析
joinPath 方法用于拼接各个路径片段, 拼接成一个以 '/' 开头的路径字符串.
import { str } from 'cat-kit/fe'
const url = str.joinPath('a', 'b', 'c')
// return '/a/b/c'
const url = str.joinPath('/a', '/b', '/c')
// return '/a/b/c'
const url = str.joinPath('/a', 'b', '/c')
// return '/a/b/c'
静态资源
requireImg
引入本地静态图片
requireImg('ship')
//return http://localhost:2001/src/assets/ship.jpg
requireImg('ship.png', '/test', 'png')
//return http://localhost:2001/test/ship.png
requireImg(['ship', 'train'])
//return ['http://localhost:2001/src/assets/ship.jpg','http://localhost:2001/src/assets/train.jpg']