@otwb/common
v2.0.7
Published
otwb 通用工具库
Readme
@otwb/common 通用工具库
许可证
MIT
安装
npm i @otwb/common部分功能需要您安装依赖
vue@3。
基础工具
@otwb/common/array 数组
removeIf 移除数组中符合条件的元素
declare function removeIf<T>(array: T[], condition: (data: T, index: number) => boolean, once: true): T | undefined
declare function removeIf<T>(array: T[], condition: (data: T, index: number) => boolean, once?: false): T[]- 参数
array:待处理的数组 - 参数
condition:判断条件 - 参数
once:是否只移除第一个符合条件的元素,默认 false - 返回值:移除的元素
示例:
const array = [1, 2, 3, 4, 5]
removeIf(array, (item) => item > 2)
// [1, 2]
const array = [1, 2, 3, 4, 5]
removeIf(array, (item) => item > 2, true)
// 3@otwb/common/code 代码
formatCode 格式化代码,使用 prettier
declare function formatCode(
code: string,
lang: 'js' | 'ts' | 'css' | 'html' | (string & {}),
options?: import('prettier').Options,
): Promise<string>- 参数
code:待格式化的代码 - 参数
lang:代码的语言 - 参数
options:prettier 选项 - 返回值:格式化后的代码
示例:
await formatCode('console.log("Hello World")', 'js')
// console.log("Hello World");
await formatCode('console.log("Hello World")', 'js', { semi: false, singleQuote: true })
// console.log('Hello World');@otwb/common/color 颜色
isDarkColor 判断颜色是否为暗色
declare function isDarkColor(color: string): boolean- 参数
color:待判断的颜色 - 返回值:是否为暗色
示例:
isDarkColor('#000000')
// true
isDarkColor('#ffffff')
// falsebrightness 提亮颜色 (hsv 色彩空间的 v)
declare function brightness(color: string, amount: number): string- 参数
color:待处理的颜色 - 参数
amount:提亮的度,负数时亮度降低 - 返回值:处理后的颜色
示例:
brightness('#18a058', 1)
// #36ad6a
brightness('#18a058', -1)
// #0c7a43toRGB 颜色转 RGB
declare function toRGB(color: string): [r: number, g: number, b: number]- 参数
color:待转换的颜色 - 返回值:RGB 数组
示例:
toRGB('#18a058')
// [24, 160, 88]getLightness 获取颜色的亮度(hsl 色彩空间的 l)
declare function getLightness(color: string): number- 参数
color:待处理的颜色 - 返回值:亮度
示例:
getLightness('#18a058')
// 36.07843137254902getAlpha 获取颜色的透明度
declare function getAlpha(color: string): number- 参数
color:待处理的颜色 - 返回值:透明度
示例:
getAlpha('rgba(255, 0, 0, 0.5)')
// 0.5@otwb/common/dom DOM
string2dom 字符串转 DOM(不安全版本,使用 innerHTML)
declare function string2dom<T extends HTMLElement = HTMLElement>(text: string): T- 参数
text:待转换的字符串 - 返回值:DOM
示例:
string2dom('<div>Hello World</div>')
// <div>Hello World</div>string2domSafely 字符串转 DOM,(安全版本,使用 DOMParser)
declare function string2domSafely<T extends HTMLElement = HTMLElement>(text: string): T- 参数
text:待转换的字符串 - 返回值:DOM
示例:
string2domSafely('<div>Hello World</div>')
// <div>Hello World</div>@otwb/common/excel Excel
table2Excel 表格转 Excel
拆分开
thead与tbody,可以更好的配合组件库的表格组件
declare function table2Excel(table: HTMLTableElement, sheetName?: string): Blob
declare function table2Excel(thead: HTMLTableSectionElement, tbody: HTMLTableSectionElement, sheetName?: string): Blob- 参数
table:待转换的表格 - 参数
thead:待转换的表头 - 参数
tbody:待转换的表格体 - 参数
sheetName:工作表名称,默认 Sheet1 - 返回值:Blob
示例:
table2Excel(document.querySelector('table'))
table2Excel(document.querySelector('thead'), document.querySelector('tbody'))
// Blob { size: 1024, type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }@otwb/common/fn 函数工具
isFunction 判断是否为函数
declare function isFunction(val: unknown): val is Function- 参数
val:待判断的值 - 返回值:是否为函数
示例:
isFunction(() => {})
// true
isFunction({})
// falsedebounce 创建一个去抖函数,延迟调用func直到wait之后
如果
leading和trailing选项为true,则func为仅当去抖动函数在超时的后沿调用。 如果wait为 0 且leading为false,则推迟func调用直到下一个刻度,类似于超时为 0 的 setTimeout。 如果在有requestAnimationFrame的环境中省略wait,func调用将被推迟到绘制下一帧(通常约为 16 毫秒)。
declare function debounce<Fn extends (...args: any[]) => any>(
fn: Fn,
wait?: number,
options?: {
leading?: boolean
trailing?: boolean
maxWait?: number
},
): Fn & {
cancel: () => void
flush: () => ReturnType<Fn>
pending: boolean
}- 参数
fn:执行的函数 - 参数
wait:防抖时间,单位毫秒,默认 0. - 参数
options:选项- 参数
options.leading:在超时前调用,默认 false. - 参数
options.trailing:在超时后调用,默认 true. - 参数
options.maxWait:最大等待时长.
- 参数
- 返回值:处理后的函数
cancel:取消执行.flush:立即执行.pending:是否正等待执行.
示例:
const fn = debounce(() => console.log('hello world'), 1000)
fn()
setTimeout(fn, 500)
// 1.5s 后输出 'hello world'throttle 创建一个节流函数,在每个wait时长内最多执行一次
如果
leading和trailing选项为true,则func为仅当去抖动函数在超时的后沿调用。 如果wait为 0 且leading为false,则推迟func调用直到下一个刻度,类似于超时为 0 的 setTimeout。 如果在有requestAnimationFrame的环境中省略wait,func调用将被推迟到绘制下一帧(通常约为 16 毫秒)。
declare function throttle<Fn extends (...args: any[]) => unknown>(
fn: Fn,
wait?: number,
options?: {
leading?: boolean
trailing?: boolean
},
): Fn & {
cancel: () => void
flush: () => ReturnType<Fn>
pending: boolean
}- 参数
fn:执行的函数 - 参数
wait:节流时间,单位毫秒,默认 0. - 参数
options:选项- 参数
options.leading:在超时前调用,默认 true. - 参数
options.trailing:在超时后调用,默认 true. - 参数
options.maxWait:最大等待时长.
- 参数
- 返回值:处理后的函数
cancel:取消执行.flush:立即执行.pending:是否正等待执行.
示例:
const fn = throttle(() => console.log('hello world'), 1000)
fn()
setTimeout(fn, 500)
// 1s 后输出 'hello world'@otwb/common/mime MIME
getType 根据扩展名获取 MIME 类型
declare function getType(extensionOrPath: string): string | undefined- 参数
extensionOrPath扩展名或路径。如 .png zip xxx.dat - 返回值:MIME类型。如:text/plain 示例:
getType('.png')
// 'image/png'getExtensions 根据 MIME 类型获取扩展名
declare function getExtensions(type: string): string[] | undefined- 参数
type:MIME类型。如:text/plain - 返回值:扩展名数组。如:['.png']
示例:
getExtensions('image/png')
// ['png']@otwb/common/object 对象
clone 克隆对象(深拷贝)
包括原型、函数和循环引用
declare function clone<T extends {}>(obj: T): T- 参数
obj:待克隆的对象 - 返回值:克隆后的对象
示例:
const obj = { a: 1, b: { c: 2 } }
const cloned = clone(obj)
// { a: 1, b: { c: 2 } }
console.debug(cloned === obj, cloned.b === obj.b)
// false falsecopy 简单的深拷贝
使用
JSON.stringify和JSON.parse实现
declare function copy<T extends {}>(obj: T): T- 参数
obj:待复制的对象 - 返回值:复制后的对象
示例:
const obj = { a: 1, b: { c: 2 } }
const copied = copy(obj)
// { a: 1, b: { c: 2 } }
console.debug(copied === obj, copied.b === obj.b)
// false falseomitProps 移除对象的指定属性
declare function omitProps<T extends {}, Key extends keyof T | (string & {})>(obj: T, ...keys: Key[]): Omit<T, Key>- 参数
obj:待处理的对象 - 参数
keys:待移除的属性 - 返回值:处理后的对象
示例:
const obj = { a: 1, b: 2, c: 3 }
omitProps(obj, 'a', 'b')
// { c: 3 }pickProps 从对象中挑选指定属性
declare function pickProps<T extends {}, Key extends keyof T | (string & {})>(obj: T, ...keys: Key[]): Pick<T, Key>- 参数
obj:待处理的对象 - 参数
keys:待挑选的属性 - 返回值:处理后的对象
示例:
const obj = { a: 1, b: 2, c: 3 }
pickProps(obj, 'a', 'b')
// { a: 1, b: 2 }isDiff 比较两个对象是否有差异
declare function isDiff<O1, O2>(obj1: O1, obj2: O2, options?: IsDiffOptions): boolean
interface IsDiffOptions {
ignore?: string[] | ((k: string) => boolean | undefined | void)
}- 参数
obj1:待比较的对象 - 参数
obj2:待比较的对象 - 参数
options:选项- 参数
options.ignore:忽略的属性
- 参数
- 返回值:是否有差异
示例:
isDiff({ a: 1, b: 2 }, { a: 1, b: 2 })
// false
isDiff({ a: 1, b: 2 }, { a: 1, b: 3 })
// true
isDiff({ a: 1, b: 2 }, { a: 1, b: 3 }, { ignore: ['b'] })
// falseisNone 判断对象是否为空
declare function isNone(val: unknown): boolean- 参数
val:待判断的值 - 返回值:是否为空
示例:
isNone(null)
// true
isNone(undefined)
// true
isNone('')
// true
isNone(' ')
// true
isNone(0)
// false
isNone(Infinity)
// false
isNone(NaN)
// true
isNone(false)
// false
isNone([])
// true
isNone([1])
// false
isNone({})
// true
isNone({ a: 1 })
// falseisNullish 判断对象是否为 nullish
declare function isNullish(val: unknown): val is null | undefined- 参数
val:待判断的值 - 返回值:是否为 nullish
示例:
isNullish(null)
// true
isNullish(undefined)
// true
isNullish('')
// false
isNullish(0)
// false
isNullish(Infinity)
// false
isNullish(NaN)
// false
isNullish([])
// false
isNone({})
// falseisObject 判断对象是否为对象
declare const isObject: (val: unknown) => val is Record<any, any>- 参数
val:待判断的值 - 返回值:是否为对象
示例:
isObject({})
// true
isObject([])
// true
isObject(() => {})
// true
isObject('')
// false
isObject(0)
// false
isObject(Infinity)
// false
isObject(NaN)
// falseisPlainObject 判断对象是否为纯对象
declare function isPlainObject(val: unknown): val is object- 参数
val:待判断的值 - 返回值:是否为纯对象
示例:
isPlainObject({})
// true
isPlainObject([])
// false
isPlainObject(() => {})
// false
isPlainObject('')
// false
isPlainObject(0)
// false
isPlainObject(Infinity)
// false
isPlainObject(NaN)
// falsemerge 合并对象
declare function merge(...objects: any[]): any- 参数
objects:待合并的对象 - 返回值:合并后的对象
示例:
const obj1 = { a: 1, b: 2 }
const obj2 = { c: 3, d: 4 }
merge(obj1, obj2)
// { a: 1, b: 2, c: 3, d: 4 }@otwb/common/qs 查询字符串
parse 解析查询字符串
declare function parse(search: string): URLSearchParams- 参数
search:待解析的查询字符串,如:a=1&b=xxx - 返回值:解析后的查询参数对象
示例:
parse('a=1&b=2&c=3')
// URLSearchParams { 'a' => '1', 'b' => '2', 'c' => '3' }stringify 将查询参数对象转换为查询字符串
declare function stringify(object: Record<string, MaybeArray<string | number | boolean> | undefined | null>): string- 参数
object:待转换的查询参数对象 - 返回值:转换后的查询字符串 示例:
stringify({ a: 1, b: 2, c: 3 })
// 'a=1&b=2&c=3'@otwb/common/save 数据保存
saveAs尝试使用showSaveFilePicker保存文件,如果该 API 未可用 则调用downloadAs。
saveAs 保存为文件
declare function saveAs(content: MaybePromise<Response | Blob | ReadableStream>, name?: string): Promise<void>- 参数
content:待保存的内容 - 参数
name:保存的文件名 - 返回值:promise
示例:
saveAs(new Blob(['Hello World'], { type: 'text/plain' }), 'hello.txt')
saveAs(fetch('http://www.ithinkdt.com/cloud/doc'), 'hello.txt')downloadAs 下载为文件
declare function downloadAs(content: MaybePromise<Response | Blob | ReadableStream>, name?: string): Promise<void>- 参数
content:待下载的内容 - 参数
name:保存的文件名 - 返回值:promise
示例:
downloadAs(new Blob(['Hello World'], { type: 'text/plain' }), 'hello.txt')
downloadAs(fetch('http://www.ithinkdt.com/cloud/doc'), 'hello.txt')@otwb/common/string 字符串
measureText 测量文本宽度
declare function measureText(text: string, font: string): number- 参数
text:待测量的文本 - 参数
font:文本的字体样式 - 返回值:文本的宽度
示例:
measureText('Hello World', '16px sans-serif')
// 100a2b base64 转字符串,同 globalThis.atob,支持 Unicode
declare function a2b(data: string): string- 参数
data:待转换的 base64 字符串 - 返回值:转换后的字符串
示例:
a2b('YSDEgCDwkICAIOaWhyDwn6aE')
// 'a Ā 𐀀 文 🦄'b2a 字符串转 base64,同 globalThis.btoa,支持 Unicode
declare function b2a(str: string): string- 参数
str:待转换的字符串 - 返回值:转换后的 base64 字符串
示例:
b2a('a Ā 𐀀 文 🦄')
// 'YSDEgCDwkICAIOaWhyDwn6aE'hyphenate 驼峰转连字符
declare function hyphenate(str: string): string- 参数
str:待处理的字符串 - 返回值:处理后的字符串
示例:
hyphenate('helloWorld')
// 'hello-world'
hyphenate('helloWorld')
// 'hello-world'camelize 连字符转驼峰
declare function camelize(str: string): string- 参数
str:待处理的字符串 - 返回值:处理后的字符串
示例:
camelize('hello-world')
// 'helloWorld'capitalize 首字母大写
declare function capitalize(str: string): string- 参数
str:待处理的字符串 - 返回值:处理后的字符串
示例:
capitalize('hello world')
// 'Hello world'@otwb/common/tree 树
flattenTree 扁平化树
declare function flattenTree<T extends {}>(tree: T[], options?: FlattenTreeOptions<T>): T[]
interface FlattenTreeOptions<T extends {}> {
childrenKey?: (keyof T) & string
}- 参数
tree:待处理的树 - 参数
options:选项- 参数
options.childrenKey:子节点键名,默认 children
- 参数
- 返回值:处理后的树
示例:
const tree = [
{
id: 1,
name: 'a',
children: [
{
id: 2,
name: 'b',
children: [
{
id: 3,
name: 'c',
},
],
},
],
},
]
flattenTree(tree)
// [
// { id: 1, name: 'a', children: [{ id: 2, name: 'b', children: [{ id: 3, name: 'c' }] }] },
// { id: 2, name: 'b', children: [{ id: 3, name: 'c' }] },
// { id: 3, name: 'c' },
// ]array2Tree 数组转树
declare function array2Tree<T extends {}>(data: T[], options?: Array2TreeOptions<T>): T[]
interface Array2TreeOptions<T extends {}, KeyofT extends (keyof T) & string = (keyof T) & string> {
rootId?: string
idKey?: KeyofT
parentKey?: KeyofT
childrenKey?: KeyofT
sortKey?: KeyofT
}- 参数
data:待处理的数组 - 参数
options:选项- 参数
options.rootId:根节点ID,默认自动计算 - 参数
options.idKey:数据的ID字段名,默认 id - 参数
options.parentKey:数据的父节点ID字段名,默认 parentId - 参数
options.childrenKey:数据的下级节点字段名,默认 children - 参数
options.sortKey:数据的排序字段名
- 参数
- 返回值:处理后的树
示例:
const data = [
{ id: 1, name: 'a', parentId: 0 },
{ id: 2, name: 'b', parentId: 1 },
{ id: 3, name: 'c', parentId: 2 },
]
array2Tree(data)
// [
// {
// id: 1,
// name: 'a',
// children: [
// {
// id: 2,
// name: 'b',
// children: [
// {
// id: 3,
// name: 'c'
// }
// ]
// }
// ]
// },
// ]walkTree 遍历树
declare function walkTree<T extends {}>(
data: T[],
each: (item: T, index: number, parent: T | undefined, children: T[] | undefined) => MaybePromise<boolean | void>,
options?: WalkTreeOptions<T> & {
path?: false
async: true
},
): Promise<boolean>
declare function walkTree<T extends {}>(
data: T[],
each: (item: T, index: number, parents: T[], children: T[] | undefined) => MaybePromise<boolean | void>,
options?: WalkTreeOptions<T> & {
path: true
async: true
},
): Promise<boolean>
declare function walkTree<T extends {}>(
data: T[],
each: (item: T, index: number, parent: T | undefined, children: T[] | undefined) => boolean | void,
options?: WalkTreeOptions<T> & {
async?: false
path?: false
},
): boolean
declare function walkTree<T extends {}>(
data: T[],
each: (item: T, index: number, parents: T[], children: T[] | undefined) => boolean | void,
options?: WalkTreeOptions<T> & {
async?: false
path: true
},
): boolean
interface WalkTreeOptions<T extends {}, KeyofT extends (keyof T) & string = (keyof T) & string> {
async?: boolean
childrenKey?: KeyofT
order?: 'pre' | 'post'
}- 参数
data:待处理的树 - 参数
each:遍历函数 - 参数
options:选项- 参数
options.async:是否异步等待 each 的返回结果,默认 false - 参数
options.childrenKey:数据的下级节点字段名,默认 children - 参数
options.order:遍历顺序,默认 pre - 参数
options.path:是否返回所有祖先路径,默认 false
- 参数
- 返回值:遍历结果
示例:
const data = [{ id: 'a', children: [{ id: 'b' }] }, { id: 'c' }]
walkTree(data, (item, index, parent, children) => {
console.log(item.id, index, parent?.id)
})
// a 0 undefined
// b 0 a
// c 1 undefined@otwb/common/type 类型
MaybeArray 可能是数组的类型
declare type MaybeArray<T> = T | T[]示例:
const a: MaybeArray<string> = 'a'
a = ['a', 'b'] // okMaybePromise 可能是Promise的类型
declare type MaybePromise<T> = T | Promise<T>示例:
const a: MaybePromise<string> = 'a'
a = Promise.resolve('a') // okAwaitable 可等待的
declare type Awaitable<T> = T | PromiseLike<T>示例:
const a: Awaitable<string> = 'a'
a = {
then(onfulfilled, onrejected) {
onfulfilled('a')
},
} // okMutable 将不可变转换为可变
declare type Mutable<T> = {
-readonly [P in keyof T]: T[P]
}示例:
const a: { readonly val: string } = { val: 'a' }
a.val = 'a2' // error
const b: Mutable<typeof a> = { val: 'b' }
b.val = 'b2' // okRequiredKeys 部分键设为必须
type RequiredKeys<T, K extends keyof T = keyof T> = T & {
[P in K]-?: NonNullable<T[P]>
}示例:
const a: { val?: string } = {}
const b: RequiredKeys<typeof a, 'val'> = {} // errorPartialKeys 部分键设为可选
type PartialKeys<T, K extends keyof T = keyof T> = T & {
[P in K]?: T[P]
}示例:
const a: { val: string } = { val: 'a' }
const b: PartialKeys<typeof a, 'val'> = {} // okUnion2Intersection 联合类型转交叉类型
type Union2Intersection<Union> = (Union extends any ? (argument: Union) => void : never) extends (
argument: infer I,
) => void
? I
: never示例:
type A = Union2Intersection<'a' | 'b' | 'c'>
// type A = "a" & "b" & "c"Union2Tuple 联合类型转元组
/** 并集转元组 */
type Union2Tuple<Union> = Union2TupleRecurser<Union, []>
type Union2UoF<Union> = Union extends any ? (argument: Union) => void : never
type Union2IoF<Union> = Union2Intersection<Union2UoF<Union>>
type Firs2fUnion<Union> = Union2IoF<Union> extends { (argument: infer T): void } ? T : never
type Union2TupleRecurser<Union, Tuple extends any[]> = [
Firs2fUnion<Union>,
Exclude<Union, Firs2fUnion<Union>>,
] extends [infer First, ...infer Lasts]
? [First] extends [never]
? Tuple
: Union2TupleRecurser<Lasts, [First, ...Tuple]>
: never示例:
type A = Union2Tuple<'a' | 'b' | 'c'>
// type A = ["a", "b", "c"]@otwb/common/url URL处理
normalizeUrl 标准化URL
declare function normalizeUrl(url: string): string- 参数
url:待标准化的URL - 返回值:标准化后的URL
示例:
normalizeUrl('http://www.ithinkdt.com/cloud//doc')
// 'http://www.ithinkdt.com/cloud/doc'Request 请求
Dict 字典
简化对数据字典的使用
注册插件
import { createApp } from 'vue'
import dict from '@otwb/common/dict'
const app = createApp(...)
app.use(dict, {
fetch: (dictTypes) => {
// 从后端获取字典数据
return fetch('/api/dict', {
method: 'GET',
params: {
dictTypes: dictTypes.join(',')
},
}).then((res) => res.json())
}
})
...
app.mount('#app')字典资源使用
useDict 获取字典数据
declare function useDict<T extends object>(
dictType: MaybeRef<DictTypeKey<T>>,
options?: UseDictOptions<T>,
): UseDictReturn<DictItem<T>[]>
type DictTypeKey<T extends object = object> = (string | symbol) & {
__T?: T
}
type UseDictOptions<T extends object> = {
onGet?: (dicts: DictItem<T>[]) => void
}
type UseDictReturn<Result> = Result & {
loading: boolean
} & [result: Result, loading: Ref<boolean>]
interface _DictItemBase {
label: string
value: string
remark?: string
disabled?: boolean
}
type DictItem<T extends object = object> = T & _DictItemBase- 参数
dictType:字典类型 - 参数
options:选项- 参数
options.onGet:获取到字典数据后回调
- 参数
- 返回值:字典数据
示例
import { useDict } from '@otwb/common/dict'
// 获取字典数据
const types = useDict('type', {
onGet: (data) => {
console.debug(`已获取到字典 type`, data)
},
})
// [{ value: '1', label: '类型一' }, { value: '2', label: '类型二'}]
console.debug('字典 type 加载状态:', types.loading)
// true
// 也可以直接解构
// const [ types, typesLoading ] = useDict('type')useDictMap 获取字典映射数据
declare function useDictMap<T extends object>(
dictType: MaybeRef<DictTypeKey<T>>,
options?: UseDictOptions<T>,
): UseDictReturn<DictValueMap<T>>
type DictValueMap<T extends object = object> = Map<string, DictItem<T>>- 参数
dictType:字典类型 - 参数
options:选项- 参数
options.onGet:获取到字典数据后回调
- 参数
- 返回值:字典映射数据
示例
import { useDictMap } from '@otwb/common/dict'
const typeMap = useDictMap('type', {
onGet: (data) => {
console.debug(`已获取到字典 type`, data)
},
})
// Map {
// '1' => { value: '1', label: '类型一' },
// '2' => { value: '2', label: '类型二'}
// }
console.debug('字典 type 映射加载状态:', typeMap.loading)
// false
// 同样可以直接解构
// const [ typeMap, typeMapLoading ] = useDictMap('type')registerDict 注册字典资源
declare function registerDict<T extends object>(
dictType: DictTypeKey<T>,
getter: (getDict: <F extends object>(dictType: DictTypeKey<F>) => Promise<DictItem<F>[]>) => Promise<DictItem<T>[]>,
cached?: boolean,
): Unregister
type Unregister = () => void
declare function unregisterDict<T extends object>(dictType: DictTypeKey<T>): void- 参数
dictType:字典类型 - 参数
getter:资源加载函数 - 参数
cached:是否缓存,默认 true - 返回值:取消注册函数
示例
import { registerDict, unregisterDict } from '@otwb/common/dict'
const someDictKey = Symbol()
// 注册资源加载函数
const unregister = registerDict(someDictKey, () => {
return fetch('/api/some', {
method: 'GET',
}).then((res) => res.json())
})
// 使用字典
const options = useDict(someDictKey)
// 取消注册
unregister()
// or
unregisterDict(someDictKey)可以使用此方法从系统字典中定制数据
import { registerDict } from '@otwb/common/dict'
// 注册资源加载函数
registerDict('customKey', (getDict) => {
return getDict('dictKey').then((data) => {
return data.filter((item) => item.value !== 'some')
})
})I18n 国际化
多语言处理
注册插件
import { createApp } from 'vue'
import i18n from '@otwb/common/i18n'
const app = createApp(...)
const locale = ref('zh-CN')
app.use(i18n, {
locale,
// 未找到资源时回退的语言
defaultLocale: 'en-US',
// 关闭响应式,如果您在切换语言时刷新页面
reactive: false
})
...
app.mount('#app')定义并使用资源
使用 defineI18n 定义资源后使用
declare function defineI18n<Message extends object>(
loader: (locale: Locale) => Promise<Message>,
options?: {
reactive?: boolean
},
): I18nComposable<Message>
type I18nComposable<Message extends object> = (locale?: MaybeRef<Locale>) => I18nInstance<ParseMessage<Message>>
interface I18nInstance<ParsedMessage> {
locale: Ref<Locale>
t<Key extends keyof ParsedMessage>(this: void, key: Key): string
t<Key extends keyof ParsedMessage, Parameter extends ParsedMessage[Key] extends (p: infer P) => string ? P : never>(
this: void,
key: Key,
parameter: Parameter,
locale?: Locale,
): string
}- 参数
loader:资源加载函数 - 参数
options:选项- 参数
options.reactive:是否响应式,默认跟随插件配置
- 参数
- 返回值:国际化实例
示例
// file locales/zh-CN.ts
export default {
a: {
b: 'a.b',
c: (count: number) => `a.c: count is ${count}`,
},
d: (data: { p1: string; p2: boolean }) => `d: p1 is ${data.p1}, p2 is ${p2}`,
}
// file: use-abc-i18n.ts
import { defineI18n } from '@otwb/common/i18n'
export default defineI18n(
(locale) => {
return import(`./locales/${locale}.ts`).then((m: typeof import('./locales/zh-CN')) => m.default)
},
{
// 可单独控制资源是否为响应式
reactive: true,
},
)
// file: AbCde.tsx
import { defineComponent } from 'vue'
import useAbcI18n from './use-abc-i18n'
export default defineComponent({
name: 'AbCde',
setup() {
const { t } = useAbcI18n()
return (
<div>
<span>{t('a.b')}</span>
<span>{t('a.c', 2)}</span>
<span>{t('d', { p1: 'p1', p2: true })}</span>
</div>
)
},
})