7 posts tagged with "ts"
View All Tagsts provide/inject
ts装饰器和继承
element ui省市区地区选择器
需求场景
element ui一直没有开箱即用省市区地区选择器,可能是考虑国际化的原因。想要实现,可以基于cascader组件。那么问题来了,哪里有稳定持续维护的省市区数据源?看到不少文章使用的是`element-china-area-data`npm 包,看了下数据源已经很久没更新了,此外这个包的省市区还加上了市辖区三个字,感觉没啥意义。
解决方案
由于移动端经常使用vant组件库,里面的Area组件刚好提供了数据源npm包https://www.npmjs.com/package/@vant/area-data,为了保持移动端和桌面端省市区数据的一致性,于是发布了一个基于此数据源生成的符合element ui cascader组件格式的npm包https://www.npmjs.com/package/@urcloud/area-data。
实现功能
- 将vant area的数据格式转为Element UI的数据格式
- 省市区地区选择器支持全部选项
- 支持Element UI和Element Plus
数据格式
[
{
label:'北京市',
value:'110000',
children:[
{
label:'北京市',
value:'110100',
children:[
{
lable:'东城区',
value:'110101'
},
...
]
},
...
]
},
...
]
使用方式
<template>
<div class="demo-title demo-1">vant数据源:</div>
<el-cascader
v-model="value1"
:options="options1"
></el-cascader>
<div class="demo-title demo-2">vant数据源:加全部</div>
<el-cascader
v-model="value2"
:options="options2"
></el-cascader>
</template>
<script>
import {defineComponent} from 'vue';
import {getAreaTree} from '@urcloud/china-area-data';
export default defineComponent({
setup(){
return {
value1:'',
options1:getAreaTree(),
value2:'',
options2:getAreaTree(true),
}
}
})
</script>
ts中enum的使用方式
需求场景
枚举的作用类似于常量,多数情况下优先使用枚举而不是常量。
简单场景
enum Platform {
"andorid" = 1,
"ios" = 2,
}
简单场景下,推荐使用 const,因为 enum 会成对象,const 只生成常量,占用的开销少,缺点是不能遍历 enum
const enum Platform {
"andorid" = 1,
"ios" = 2,
}
复杂场景(结合 namespace)
在使用枚举时,往往会需要一个辅助函数去展示属性的值,这个时候可以配合 namespace
enum Platform {
"andorid" = 1,
"ios" = 2,
}
namespace Platform {
export function getText(value: number) {
if (value === 1) {
return "ANDORID_PLATFORM";
}
if (value === 2) {
return "IOS_PLATFORM";
}
}
}
这样写的一个好处就是枚举合辅助方法能保持在同一命名空间下,维护方便。缺点就是如果需要遍历枚举的属性,就会多出命名空间中方法属性。
2023-03-16 更新
由于 ts 目前提供的 enum 功能简单,最终也是编译成对象。使用上只是语义上更清晰了而已,但是复杂场景需要方法支持的时候并不好用。所以我的实际项目上使用 buildEnum 辅助函数生成 enum 对象(普通 Object 对象),配合 ts 的推导,可以自动提示 enum 对象的所有属性和方法。
export const ReportStatus = buildEnum(
{
ToHandle: 0,
Handled: 1,
},
[
{
symbol: "ToHandle",
label: "待处理",
},
{
symbol: "Handled",
label: "已处理",
},
]
);
export function buildEnum<T extends Record<string, string | number>>(
obj: T,
labelArr: {
symbol: string;
label: string;
}[]
) {
return Object.assign(obj, {
Options: labelArr.map((v) => {
return {
label: v.label,
value: obj[v.symbol],
};
}),
getLabel(value: string | number) {
const macthed = labelArr.filter((v) => obj[v.symbol] == value)[0];
return macthed?.label ?? "";
},
});
}
Object.keys在typescript中的使用
需求场景
当在ts中使用Object.keys时会报错。
Object.keys(Detail).forEach((key) => {
Detail[key] = res.data[key];
});
解决方案
看到很多解决方案,最后发现国外一大佬的解决方案是最好的,通过重新定义Object的ts声明文件解决。
type ObjectKeys<T> =
T extends object ? (keyof T)[] :
T extends number ? [] :
T extends Array<any> | string ? string[] :
never;
interface ObjectConstructor {
keys<T>(o: T): ObjectKeys<T>
}