npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

co-utils-vue

v2.5.2

Published

工具库

Readme

co-utils-vue已废弃,并且不再维护!!! 可考虑使用@eqian/utils-vue代替

介绍

npmimgCoverage Status

co-utils-vue工具库是基于typescript、vue3实现的一个常用库封装

安装

npm install co-utils-vue -D

使用

Hooks

usePick

与Pick选类似,但是usePick取指定一组属性值,返回一个新的属性值

const test = {
    book: '倚天屠龙记',
    name: '金庸',
    price: '18',
    likes: '999'
};
console.log(usePick(test, [])); // {}
console.log(usePick(test, ['name'])); // {name: '金庸'}

useTableList

表格分页数据请求,返回的数据结果应为:

{
    list | listKey: [],
    total | totalKey:0
}

配置参数

UseTableList<T = any, P = any> {
  request: {
    /**
     * 请求方法
     */
    api: (params: P) => Promise<T>;
    /**
     * 请求参数
     */
    params?: P;
    /**
     * 分页键
     * @default pageNum
     */
    pageNumKey?: string;
    /**
     * 分页键
     * @default pageSize
     */
    pageSizeKey?: string;
    /**
     * 返回结果的数据列表键
     * @default list
     */
    listKey?: string;
    /**
     * 返回结果的数据列表键
     * @default total
     */
    totalKey?: string;
    /**
     * 接口请求前处理
     */
    handleParams?: (params: P) => P;
  };
  // response?: {};
}

useFormValueWatcher

在一些场景中,有时候需要进行表单的监听而进行某些操作,例如,修改某些信息时,如果没有发生变化,不能进行编辑或者一些其他的操作,useFormValueWatcher由此诞生

// vue3 使用实例
const origin = cloneDeep(form) // 克隆原始表单数据
watch(()=>[form], ()=>{
    console.log(useFormValueWatcher(form, origin)) // 表单发生变化返回true,否则false
},{ deep: true })

useSortByKey

根据某个数组值进行排序,如数据类型是object[]形式,可以通过key自定义需要的排序的键

options配置项

| 参数 | 类型 | 默认值 | 说明 | | ----------- | ------------ | ------ | ------------------ | | order | dec | asc | dec | | key | object的键 | | | | compareFn | Funtion | - | 提供自定义比较函数 |

useMerge

useMerge 使用了递归的方式,可以深度合并多个对象,对于相同的键名,后面的对象会覆盖前面的对象。如果键对应的值是对象,则会递归合并其内部的键值对。

示例一

  const source = {
    name: '张三',
    gender: '女'
  };
  const source1 = {
    name: '张三',
    info: '信息'
  };
const mergeRes = useMerge(source, source1)
/**
{
      name: '张三',
      gender: '女',
      info: '信息'
    }
**/

示例二

  const source = {
          name: '张三',
          gender: '女',
          info: {
            name: '张强'
          }
        }
  const source1 = {
          name: '张4',
          info: {
            age: 18
          }
        }
  const mergeRes = useMerge({}, source,source1)
  /**
  {
      name: '张4',
      gender: '女',
      info: {
        name: '张强',
        age: 18
      }
    }
  **/

示例三

useMerge<number[]>([], [1, 2], [3, 4])) //[3, 4]

useMerge(
        {},
        {
          name: '张三',
          gender: '女'
        },
        {
          name: '张三',
          gender: '女'
        },
        {
          name: '张三',
          gender: '女',
          info: [520]
        }
      )
/**
      name: '张三',
      gender: '女',
      info: [520]
**/

useEmptyObject

useEmptyObject用于将对象值深度置空,会根据传入的对象值进行判断并赋予对应的空值。它接收两个参数data和defaultValue其中data是一个泛型,表示要清空的对象,defaultValue是一个部分类型* 它与data的类型一致,用于设置每个属性的初始值。在设置属性的初始值时,使用defaultValue对应字段的值来替换原有的属性值。最后,返回清空后的 data 对象.

示例一

  const data = {
    key: '8899797',
    nested: {
      ll: '123',
      deep: {
        nestedKey: 'nestedValue'
      }
    }
  };
useEmptyObject(data)
/**
{
    key: '',
    nested: {
      ll: '',
      deep: {
        nestedKey: ''
      }
    }
  }
**/

示例二

  const data = {
    key: '8899797',
    nested: {
      ll: '123',
      deep: {
        nestedKey: 'nestedValue'
      }
    }
  };
useEmptyObject(data, {
        nested: {
          deep: {
            nestedKey: '8888'
          }
        }
      })
/**
{
      key: '',
      nested: {
        ll: '',
        deep: {
          nestedKey: '8888'
        }
      }
    }
**/

useChunk

将数组数据进行分片,内部做了正无穷负无穷处理

useChunk(['a', 'b', 'c', 'd'], 0) // => []
useChunk(['a', 'b', 'c', 'd'], 2) // => [['a', 'b'], ['c', 'd']]
useChunk(['a', 'b', 'c', 'd'], 3) // => [['a', 'b', 'c'], ['d']]
useChunk(['a', 'b', 'c', 'd'], 3.5) // => [['a', 'b', 'c'], ['d']]
useChunk(['a', 'b', 'c', 'd'], 1 / 0) // => [['a'], ['b'], ['c'], ['d']]
useChunk(['a', 'b', 'c', 'd'], -1 / 0) // => []

useFormatDate

useFormatDate将时间进行格式化输出,支持时间戳、标准时间等。date参数为转换时间,format默认输出格式yyyy-MM-dd

  • 时间戳
console.log('时间戳', useFormatDate(1669290652000) ) // 2022-11-24
  • 时间
console.log('时间戳', useFormatDate(new Date()) ) // 2022-11-24
  • 指定格式
console.log('时间戳', useFormatDate(new Date(), 'yyyy-MM-dd HH:mm:ss') ) // 2022-11-24 19:50:52

useBeforeDate

useBeforeDate接收一个时间参数,与当前时间比较,计算早于当前时间差,接收两个参数,date比较的时间(必须),此外,还可以传入resDefault,设置默认返回值,默认返回空值,(如果晚于当前时间的返回值)

  • 早于当前时间
console.log(useBeforeDate('2021-11-25 19:50:52', '-')) // 1年前
console.log(useBeforeDate('2022-11-17 19:50:52', '-')) // 1周前
console.log(useBeforeDate('2022-11-25 19:50:52', '-')) // 54分钟前
  • 晚于当前时间
console.log(useBeforeDate('2022-11-27 19:50:52', '-')) // -

usePriceToThousand

usePriceToThousand金额千分位转换,参数price可以是数字或者字符串类型;参数decimals需要保留小数点 默认2;参数separator千分位符号 默认,;参数round 为true时保留位数向下取整,否则向上取整,默认为true

console.log(usePriceToThousand(3600)) // 3,600.00
console.log(usePriceToThousand(3600.2566)) // 3,600.25
console.log(usePriceToThousand(3600.2566,1,'-', false)) // 3-600.2
console.log(usePriceToThousand('9655544.58777',3,'-')) // 9-655-544.587

useFormatBytes

useFormatBytes将文件字节转换成 MB等格式

参数bytes可以是number类型;参数`decimals需要保留小数点 默认2

useEncryptedIdCard

useEncryptedIdCard身份证脱敏处理

console.log(useEncryptedIdCard("450616199905206666")) // 450616****6666
console.log(useEncryptedIdCard("3600.2566")) // Error: 3600.2566 is invalid idCard

useEncryptedPhone

desPhone手机号脱敏处理

console.log(useEncryptedPhone("19994402299")) // 199****2299
console.log(useEncryptedPhone("3600.2566")) // Error: 3600.2566 is invalid phone number

useCloneDeep

useCloneDeep实现数据拷贝,参数source拷贝的原数据内容

useCamelize

useCamelize短杆拼接转驼峰,test-icon => testIcon

useCamelizeToKebabCase

useCamelizeToKebabCase驼峰命名转短杆或者下划线命名,接收参数str命名字符串,mark支持传入-或者下划线进行拼接,默认为短杆-,userName => user-name

useFirstLetterToUpperCase

useFirstLetterToUpperCase首字母转大写

useFirstLetterToUpperCase

useFirstLetterToUpperCase首字母大写转小写

useToFixedFix

useToFixedFix处理小数点, 参数decimals保留的小数点位数,默认为2小数位

console.log(useToFixedFix("45588.28988, 3")) // 45588.289
console.log(useToFixedFix("45588.28988, 2")) // 45588.28
console.log(useToFixedFix("45588.28988, 1")) // 45588.2
console.log(useToFixedFix("45588.28988, 0")) // 45588
console.log(useToFixedFix("45588.28, 3")) // 45588.28

useTransformTree

useTransformTree数组数据转树形结构,useTransformTree具有两个参数,arrData是必须的数组数据,options参数是可选项,parent是可选的绑定父节点字段,默认为parent,key 默认是可选的每组数据的唯一标识字段,默认值为id(这两个字段是可以自定义的),pid字段是作为父节点时的值,默认为null

options参数

{
  parent: string;
  key: string;
  pid: string | number | null;
}

如果你的数据,没有像上面数据的id字段,此时,你需要传入pid参数设置成你的标识字段,同样的,如果你绑定的父节点字段不是parent,那么此时,你需要传入parent字段设置你的父节点字段

const arr = [{ parent: null, id: 1, name: '北京' },
{ parent: 1, id: 11, name: '朝阳' },
{ parent: 11, id: 111, name: '朝阳1号' },
{ parent: 1, id: 12, name: '海淀' },
{ parent: 12, id: 121, name: '海淀1号' },
{ parent: null, id: 2, name: '上海' },
{ parent: 2, id: 21, name: '浦东' },
{ parent: 21, id: 211, name: '浦东1号' },
{ parent: 2, id: 22, name: '虹口' },
{ parent: 22, id: 221, name: '虹口1号'}]

// 转换后
[
  {
    "parent": null,
    "id": 1,
    "name": "北京",
    "children": [
      {
        "parent": 1,
        "id": 11,
        "name": "朝阳",
        "children": [
          {
            "parent": 11,
            "id": 111,
            "name": "朝阳1号"
          }
        ]
      },
      {
        "parent": 1,
        "id": 12,
        "name": "海淀",
        "children": [
          {
            "parent": 12,
            "id": 121,
            "name": "海淀1号"
          }
        ]
      }
    ]
  },
  {
    "parent": null,
    "id": 2,
    "name": "上海",
    "children": [
      {
        "parent": 2,
        "id": 21,
        "name": "浦东",
        "children": [
          {
            "parent": 21,
            "id": 211,
            "name": "浦东1号"
          }
        ]
      },
      {
        "parent": 2,
        "id": 22,
        "name": "虹口",
        "children": [
          {
            "parent": 22,
            "id": 221,
            "name": "虹口1号"
          }
        ]
      }
    ]
  }
]

useTransformList

useTransformList树形结构数据进行扁平化,其中在每一组数据中,应该包含children字段,如果不是该字段,那么此时应该传入可选参数options进行替换

interface ITreeOptions {
  /**
   * 子节点的键 默认值【children】
   */
  children?: string;
  /**
   * 父节点ID的键 默认值【id】
   */
  pidKey?: string;
  /**
   * 设置父节点的属性值 默认值【null】
   */
  pidValue?: string | number | null;
  /**
   * 设置父节点键 默认值【parent】
   */
  parentKey?: string;
  /**
   * 是否需要设置父节点标志 默认值【true】
   */
  pidFlag?: boolean;
}

useSFCWithInstall

useSFCWithInstall进行组件注册,接受一个组件作为参数

useWebSocket

useWebSocket基于websocket进行封装;具备心跳检测,断线重连等功能机制。

例子,在vue文件中,你可以这样使用:

const { ws, send, websocketOpen, data } = useWebSocket(
  url,
  {
    reconnectCount: 5,
    autoClose: true,
    onOpen: () => {
      console.log('链接成功');
    },
    onError: () => {
      console.log('链接失败1');
    },
    onClose: () => {
      console.log('连接关闭');
    },
    onFailed: () => {
      console.log('重连失败');
    }
  }
);

你应该注意的是,如果开启了心跳检测,默认的心跳信息是ping,并且如果能够从服务器中得到的响应信息也是ping,即相同于心跳信息,此时,数据将会被过滤,因此,在发送数据时,尽量避免与心跳信息的数据一致,你可以通过设置heartMessage来设置你的心跳数据。

属性

| 属性名 | 类型 | 默认值 | 说明 | 可选 | | -------------- | ------------------ | ------ | ---------------------------------------------------------- | ---- | | url | string | - | 链接的通道的地址 | 否 | | protocols | string | string[] | - | 通信协议,可接受ws或者wss协议 | 是 | | heartTime | number | 5000 | 心跳时间间隔,需要需要开启isOpenHeart属性,才可生效 | 是 | | heartMessage | string | ping | 心跳信息,默认为ping,需要开启isOpenHeart属性,才可生效 | 是 | | isReconnect | boolean | true | 是否自动重连,需要开启isOpenHeart属性,才可生效 | 是 | | reconnectTime | number | 5000 | 重连时间间隔,需要开启isOpenHeart属性,才可生效 | 是 | | reconnectCount | number | fn | -1 | 重连次数 -1 则不限制,可以是一个方法,需要返回一个boolean | 是 | | autoClose | boolean | true | 自动关闭,关闭浏览器或者实例销毁时触发 | 是 | | onOpen | fn | | 连接成功地回调 | 是 | | onClose | fn | | 关闭的回调 | 是 | | onMessage | fn | | 消息的回调 | 是 | | onError | fn | | 错误的回调 | 是 | | onFailed | fn | | 重连次数达到峰值失败回调 | 是 |

配置项

export interface ISocketOptions {
  /**
   * 通信协议
   */
  protocols?: string | string[];
  /**
   * 心跳时间间隔
   * @default 5000
   */
  heartTime?: number;
  /**
   * 心跳信息
   * @default ping
   */
  heartMessage?: string;
  /**
   * 自动关闭
   */
  autoClose?: boolean;
  /**
   * 是否自动重连
   * @default true
   */
  isReconnect?: boolean;
  /**
   * 重连时间间隔
   * @default 5000
   */
  reconnectTime?: number;
  /**
   *  重连次数
   *  可以是数值或者返回一个boolean
   *  @default -1
   */
  reconnectCount?: number | (() => boolean);
  /**
   * 连接成功地回调
   * @param ws
   */
  onOpen?: (ws: WebSocket) => void;
  /**
   * 关闭的回调
   * @param ws
   * @param e
   */
  onClose?: (ws: WebSocket, e: CloseEvent) => void;
  /**
   * 消息的回调
   * @param ws
   * @param e
   */
  onMessage?: (ws: WebSocket, e: MessageEvent) => void;
  /**
   * 错误的回调
   * @param ws
   * @param e
   */
  onError?: (ws: WebSocket, e: Event) => void;
  /**
   * 重连失败回调
   */
  onFailed?: () => void;
}
export interface ISocketReturn<T> {
  data?: Ref<T | null>;
  close: WebSocket['close'];
  websocketOpen: () => void;
  send: (data: string | ArrayBuffer | Blob, useBuffer?: boolean) => boolean;
  ws: Ref<WebSocket | undefined>;
}

Is

isPhone

isPhone校验大陆手机号

console.log(isPhone("19994403399")) // true
console.log(isPhone("15448896666774")) // false

isIdCard

isIdCard接收一个字符串,判断是否是15或者18位身份证

console.log(isIdCard('450603199906273529')) // true
console.log(isIdCard('45060319990886273529')) // false

isObjectLike

返回当前是否是object类型

console.log(isObjectLike({})) // true
console.log(isObjectLike([1, 2, 3])) // true
console.log(isObjectLike(Function)) // false
console.log(isObjectLike(null)) // false

isNumber

用于检测值是否是number数值类型

console.log(isNumber('-12.22')) // false
console.log(isNumber(-12.22)) // true

isNumeric

用于检测值是否是数字数值类型,包含正数负数,可以说是isNumber的增强版

console.log(isNumeric('1222')) // true
console.log(isNumeric('+1222')) // true
console.log(isNumeric('-1222')) // true
console.log(isNumeric('12.22')) // true
console.log(isNumeric('+12.22')) // true
console.log(isNumeric(+12.22)) // true
console.log(isNumeric('3.14e-10')) // true
console.log(isNumeric('abc')) // false
console.log(isNumeric('458.a')) // false
console.log(isNumeric('122e')) // false

isEmpty

用于检测值是否为空

isArray

用于检测值是否为一个数组

isArray(null)
// false
isArray([])
// true

其他

getTag

getTag获取数据的toString类型

console.log(getTag("1999-12-25")) // [object String]
console.log(getTag(78888)) // [object Number]
console.log(getTag({})) //  [object Object]
console.log(getTag([])) //  [object Array]
console.log(getTag(null)) //  [object Null]
console.log(getTag(undefined)) //  [object Undefined]
console.log(getTag(Object)) //  [object Function]

Omit

Omit剔除某些属性,然后返回一个新类型

interface ITest {
    name: string;
    age: number;
    sex: string;
}
type TTest = Omit<ITest, 'age' | 'sex'>;
// 相当于
interface ITest1 {
    name: string;
}

Pick

Pick选取指定一组属性,返回一个新的类型定义

interface ITest {
    name: string;
    age: number;
    sex: string;
}
type TTest = Pick<ITest, 'age' | 'sex'>;

// 相当于
interface ITest1 {
    age: number;
    sex: string;
}

Partial

Partial将类型中所有选项变为可选

interface ITest {
    name: string;
    age: number;
    sex: string;
}
type TTest = Partial<ITest>;

// 相当于
interface ITest1 {
    name?: string;
    age?: number;
    sex?: string;
}

Required

Required将类型中所有选项变为必选

interface ITest {
    name?: string;
    age?: number;
    sex?: string;
}
type TTest = Required<ITest>;

// 相当于
interface ITest1 {
    name: string;
    age: number;
    sex: string;
}

Record

Record将 K 中的所有属性值都转换为 T 类型,并返回新的对象类型

type ITest = 'name' | 'age' | 'address' | 'phone' | 'email' | 'id'

interface ITestModel {
    test: string;
    other: string;
}
type TTest = Record<ITest, ITestModel>;

// 相当于
interface ITest1 {
    name: ITestModel;
    age: ITestModel;
    address: ITestModel;
    phone: ITestModel;
    email: ITestModel;
    id: ITestModel;
}

Extract

Extract提取T中可以赋值给U的类型

type ITestModel =  'name' | 'age' | 'address' | 'phone' | 'email' ;

type TTest = Extract<ITestModel, 'name' | 'phone'>;

// 相当于
type TTest = "name" | "phone"

Exclude

Exclude从T中剔除可以赋值给U的类型

type ITestModel =  'name' | 'age' | 'address' | 'phone' | 'email' ;

type TTest = Exclude<ITestModel, 'name' | 'phone'>;

// 相当于
type TTest1 = "age" | "address" | "email"