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

common-utils-kit

v1.1.40

Published

`common-utils-kit` 是一个基于 Vue 2 和 Element UI 的公共能力包,当前同时提供:

Downloads

645

Readme

Common Utils Kit

common-utils-kit 是一个基于 Vue 2 和 Element UI 的公共能力包,当前同时提供:

  • 通用工具方法
  • 自定义指令
  • 请求封装
  • WebSocket 封装
  • Element UI 业务组件

当前版本:1.1.39

安装

npm install common-utils-kit

依赖要求:

  • vue 2.x
  • element-ui >=2.13.2

目录能力

主入口

主入口 common-utils-kit 当前导出:

  • default:Vue 插件入口,支持 Vue.use(CommonUtilsKit) 挂载 $kit 并注册公共指令
  • test
  • format
  • tool
  • file
  • confirm
  • request
  • websocket
  • table
  • directive
import {
  test,
  format,
  tool,
  file,
  confirm,
  request,
  websocket,
  table,
  directive,
} from 'common-utils-kit';

Element 组件入口

common-utils-kit/element 当前导出:

  • View3D
  • ScreenScale
  • ConfirmDialog
  • ElementForm
  • ElementTable
  • ScrollTable
  • ResetDrawer
  • ResetDialog
import {
  View3D,
  ScreenScale,
  ConfirmDialog,
  ElementForm,
  ElementTable,
  ScrollTable,
  ResetDrawer,
  ResetDialog,
} from 'common-utils-kit/element';

样式

import 'common-utils-kit/lib/utils-kit.css';

快速开始

1. 通过 Vue.use 挂载常用能力

import Vue from 'vue';
import CommonUtilsKit from 'common-utils-kit';

Vue.use(CommonUtilsKit);

安装后会在 Vue.prototype 上挂载 $kit,并自动注册 directive 中的全局指令:

this.$kit.format.getProperty(data, 'user.name');
this.$kit.table.sortMergeData(list, 'region');
this.$kit.confirm.customConfirm({ title: '提示', toolTips: '确认执行当前操作?' });

2. 局部使用

import { confirm, table } from 'common-utils-kit';

confirm.customConfirm({ title: '提示', toolTips: '确认执行当前操作?' });

const sorted = table.sortMergeData(list, 'region');

工具能力

test

常用校验能力:

  • hasValue
  • valueType
  • email
  • mobile
  • url
  • idCard
  • carNo
  • amount
  • chinese
  • letter
  • landline
  • code
import { test } from 'common-utils-kit';

test.email('[email protected]');
test.mobile('13800138000');

format

常用数据处理能力:

  • getProperty
  • unrepeated
  • treeToFlat
  • flatToTree
  • recursionFunction
  • filterData
  • dateDiff
  • getNowDate
  • setFormColumnsData
import { format } from 'common-utils-kit';

const flatList = format.treeToFlat(treeData);
const treeData = format.flatToTree(list);

tool

提供:

  • debounce
  • throttle
  • sleep
import { tool } from 'common-utils-kit';

await tool.debounce(500);
console.log('submit');

await tool.throttle(500);
console.log('throttle submit');

file

提供:

  • downloadBase64File
  • downloadFiles
  • fileToBase64
  • base64ToFile
  • base64ToFileBlob
  • uploadCompress
import { file } from 'common-utils-kit';

file.downloadFiles('https://example.com/demo.pdf', 'demo.pdf');

confirm

当前主用方法是 customConfirm,统一从主入口使用,不再从 element-ui 目录单独引用。

import { confirm } from 'common-utils-kit';

const res = await confirm.customConfirm({
  title: '操作确认',
  toolTips: '确认执行当前操作?',
  titleIcon: 'el-icon-warning-outline',
  tipIcon: 'el-icon-warning',
});

console.log(res.flag);

输入弹窗示例:

const res = await confirm.customConfirm({
  title: '填写原因',
  dialogType: 'input',
  toolTips: '请输入本次操作原因',
  inputPlaceholder: '请输入原因',
  inputValue: '',
});

console.log(res.flag, res.inputValue);

常用参数:

  • title
  • dialogType
  • toolTips
  • inputValue
  • inputPlaceholder
  • btnParam
  • closeOnClickModal
  • closeOnPressEscape
  • customClass
  • titleIcon
  • tipIcon

request

请求封装从 request 模块获取。

import { request } from 'common-utils-kit';

const http = new request.RequestHttp({
  baseURL: '/api',
  timeout: 60000,
  withCredentials: true,
}, {
  getToken: () => localStorage.getItem('token'),
  tokenHeader: 'token',
  codeKey: 'code',
  successCode: 200,
  overdueCode: 401,
  repeat: 'latest',
  showLoading: () => {},
  hideLoading: () => {},
  handleBusinessError(data, response) {
    const messageMap = {
      401: '登录已过期,请重新登录',
      403: '暂无权限访问',
      500: '服务异常,请稍后重试',
    };
    Message.error(messageMap[data.code] || data.msg || '请求失败');
    return Promise.reject(data);
  },
  handleHttpError(error) {
    const status = error.response && error.response.status;
    const messageMap = {
      400: '请求参数错误',
      401: '登录已过期,请重新登录',
      404: '接口不存在',
      500: '服务器异常',
    };
    Message.error(messageMap[status] || error.message || '请求失败');
    return Promise.reject(error);
  },
});

http.request({ method: 'get', url: '/user/info', params: { id: 1 } });
http.get('/user/info', { id: 1 }, { cancel: true, loading: false });
http.post('/user/save', { name: '张三' });

模块公开能力:

  • RequestHttp:可实例化请求类。
  • createRequest(requestConfig, options):函数式创建 RequestHttp 实例。
  • requestEnum:默认响应码配置,包含 SUCCESSOVERDUETIMEOUT
  • AxiosCanceler:请求取消管理类。
  • getPendingUrl(config):按 requestKey 或请求方法、地址、参数生成重复请求标识。

状态码处理说明:

  • codeKey 用于配置后端业务状态码字段,默认是 code,例如后端返回 status 时可传 codeKey: 'status'
  • successCode / overdueCode 支持 0false 等有效值,不会被默认值覆盖。
  • requireCode: true 时,响应体没有 codeKey 指定字段会以 ERR_MISSING_RESPONSE_CODE 拒绝。
  • 响应体为 nullundefined 时会以 ERR_EMPTY_RESPONSE 拒绝,避免把异常空响应当成功。
  • handleBusinessError(data, response) 用于自定义后端业务状态码逻辑。
  • handleHttpError(error) 用于自定义 HTTP 错误、网络错误、超时等异常逻辑。
  • RequestHttp 不内置任何状态码提示文案;未传入错误处理函数时,只会将错误原样 Promise.reject 给使用方。
  • 多个请求同时开启 loading 时,内部会维护实例级 loadingCount;只有第一个请求触发 showLoading,全部请求结束后才触发 hideLoading

重复请求和竞态处理:

// 查询类:只保留同一 requestKey 的最后一次结果,旧响应晚返回时会以 ERR_STALE_REQUEST 拒绝。
http.get('/order/list', { tab: 2 }, {
  requestKey: 'order-list-tab',
  repeat: 'latest',
});

// 分页类:pageNum 每次变化,但忽略 pageNum 后仍归为同一类请求。
http.get('/order/list', { pageNum: 2, pageSize: 10 }, {
  repeat: 'latest',
  repeatIgnoreParams: ['pageNum'],
});

// 操作类:第一个请求完成前拒绝重复提交,第二次请求会以 ERR_DUPLICATE_REQUEST 拒绝。
http.post('/order/next-step', { id: 1 }, {
  requestKey: 'order-next-step',
  repeat: 'first',
});

// 不处理重复请求。
http.get('/log/list', {}, {
  repeat: 'none',
});

请求取消能力:

import { request } from 'common-utils-kit';

const canceler = new request.AxiosCanceler({ type: 'abort' });

const config = {
  method: 'get',
  url: '/api/list',
  requestKey: 'list-page-query',
  params: { pageNum: 1 },
};

canceler.addPending(config);
canceler.removePending(config);
canceler.removeAllPending();

示例工程中的延迟 mock 请求:

// 先创建并保存请求实例。
let loadingInstance = null;
const http = new request.RequestHttp({}, {
  showLoading: () => {
    loadingInstance = this.$loading({ text: '请求加载中...' });
  },
  hideLoading: () => {
    loadingInstance && loadingInstance.close();
    loadingInstance = null;
  },
  handleBusinessError: data => {
    this.$message.error(data.msg || '业务请求失败');
    return Promise.reject(data);
  },
  handleHttpError: error => {
    this.$message.error(error.message || 'HTTP 请求失败');
    return Promise.reject(error);
  },
});

// 后续请求复用同一个实例,便于观察 repeat 策略。
http.get('/mock/request-list', {
  pageNum: currentPage,
  pageSize: 10,
}, {
  loading: false,
  repeat: 'latest',
  repeatIgnoreParams: ['pageNum'],
});

example/views/request.vue 中的请求示例需要先点击 创建请求实例 保存 RequestHttp 实例,后续 latest 只认最后一次first 阻止重复none 全部发出 三个按钮都复用该实例请求 vue.config.js 注册的 /mock/request-list 本地接口。本地 mock 示例不配置 baseURL,避免请求地址变成 /api/mock/request-list。接口延迟 2 秒返回;浏览器 Network 面板可以看到 pending 请求。示例里的 pageNum 每次变化,但通过 repeatIgnoreParams: ['pageNum'] 忽略页码字段,仍归为同一类请求,便于对比重复请求处理效果。

  • repeat: 'latest':连续点击时,后一次会取消同 key 下前一次未完成请求。
  • repeat: 'first':第一个同 key 请求未结束前,后续点击会直接拒绝。
  • repeat: 'none':不处理重复请求,连续点击会连续发出请求。

示例页还提供这些可点击按钮,都会请求 vue.config.js 中注册的本地 mock 接口。RequestHttp 本身不内置 UI 提示,示例页通过注入的 handleBusinessError / handleHttpError 调用 Element UI 的 $message.error,通过 showLoading / hideLoading 调用 $loading 服务展示并关闭加载动画:

  • handleBusinessError:请求 /mock/request-business-error,接口返回业务失败码,进入 handleBusinessError(data, response)
  • handleHttpError:请求 /mock/request-http-error,接口返回 HTTP 500,进入 handleHttpError(error)
  • showLoading/hideLoading:请求 /mock/request-loading,展示 Element UI loading 动画、实例级 loading 计数和回调触发顺序。
  • transformResponse:请求 /mock/request-transform,通过独立实例的 transformResponse(response) 转换响应数据。
  • requireCode 缺少 code:请求 /mock/request-no-code,通过 requireCode: true 展示 ERR_MISSING_RESPONSE_CODE,并在示例页 catch 中调用 $message.error
  • removeAllPending 手动取消:请求 /mock/request-cancel 后调用 axiosCanceler.removeAllPending(),Network 面板可看到取消请求,结果里展示 ERR_CANCELED

websocket

import { websocket } from 'common-utils-kit';

const client = websocket.createSocketClient({
  url: 'ws://example.com/socket',
  heartMessage: 'ping',
  heartTime: 60000,
  reconnectTime: 5000,
  onMessage: event => console.log(event.data),
});

client.connect();
client.send({ type: 'hello' });
client.close();

table

当前主用场景是 Element 表格合并行辅助。

import { table } from 'common-utils-kit';

const sorted = table.sortMergeData(sourceData, 'region');
const spanList = table.getMergeSpanList(sorted, 'region');
const spanMethod = table.createMergeSpanMethod(spanList, 0);

指令

通过 Vue.use(directive) 安装后,当前可用指令包括:

  • v-debounce
  • v-input-debounce
  • v-btn-debounce
  • v-btn-throttle
  • v-click-lock
  • v-relative-time
  • v-input-rule
  • v-local-loading
  • v-full-loading
  • v-el-drag-dialog

示例:

<template>
  <div>
    <el-input
      v-model="keyword"
      v-input-debounce:1000="handleSearch"
      placeholder="输入后防抖搜索"
    />

    <el-button v-btn-throttle="500" @click="handleSubmit">
      节流提交
    </el-button>
  </div>
</template>

Element 组件

ConfirmDialog

ConfirmDialog 是一个基于 el-dialog 的业务确认弹窗组件。

<template>
  <confirm-dialog
    v-model="dialogVisible"
    title="删除提示"
    dialog-type="tips"
    tool-tips="删除后数据不可恢复,是否继续?"
    :btn-param="componentBtns"
    title-icon="el-icon-warning-outline"
    tip-icon="el-icon-warning"
    @affirm="handleConfirm"
  />
</template>

<script>
import { ConfirmDialog } from 'common-utils-kit/element';

export default {
  components: {
    ConfirmDialog,
  },
  data() {
    return {
      dialogVisible: false,
      componentBtns: [
        { btnlable: '取消', type: '', flag: 'cancel' },
        { btnlable: '确认删除', type: 'danger', flag: 'confirm' },
      ],
    };
  },
  methods: {
    handleConfirm(flag, value) {
      console.log(flag, value);
      this.dialogVisible = false;
    },
  },
};
</script>

ElementForm

ElementForm 是配置型表单/展示组件。

基础用法

<template>
  <element-form
    ref="formExample"
    :columns="formColumns"
    :form-data="formData"
    :label-width="110"
    :value-width="90"
    @itemChange="itemChange"
    @handleSearch="handleSearch"
    @handleClear="handleClear"
  />
</template>

<script>
import { ElementForm } from 'common-utils-kit/element';

export default {
  components: {
    ElementForm,
  },
  data() {
    return {
      formData: {
        customerName: '',
        customerType: '',
      },
      formColumns: [
        {
          param: 'customerName',
          label: '客户名称',
          effect: 'form',
          type: 'search',
          rules: { required: true },
          proport: 8,
        },
        {
          param: 'customerType',
          label: '客户类型',
          effect: 'form',
          type: 'select',
          props: { label: 'label', value: 'value' },
          data: [],
          rules: { select: true },
          proport: 8,
        },
      ],
    };
  },
};
</script>

通过 ref 批量填充列配置

batchSetColumnData 现在通过组件实例方法提供,不需要再从内部 utils/common.js 直接引用。

created() {
  this.formColumns = this.createFormColumns();
},
mounted() {
  this.formColumns = this.$refs.formExample.batchSetColumnData({
    客户类型: [
      { label: '企业客户', value: 'company' },
      { label: '个人客户', value: 'personal' },
    ],
    客户标签: [
      { label: '重点客户', value: 'important' },
      { label: '已签约', value: 'contract' },
      { label: '待跟进', value: 'follow' },
    ],
  }, { unique: 'label', data: 'data' });
}

组件实例方法

  • submitForm():执行表单校验,返回 Boolean
  • clearValidate(param):清空校验
  • batchSetColumnData(config, props):基于当前 columns 返回新的列配置
  • setFormDisabled(disabled, params):批量设置表单项禁用状态

常见字段

  • param
  • label
  • effect
  • type
  • rules
  • proport
  • props
  • data
  • clearable
  • filterable
  • multiple
  • disabled

支持的常见类型

  • input
  • select
  • cascader
  • date
  • checkbox
  • radio
  • textarea
  • search

ElementTable

ElementTable 是配置型表格组件,支持:

  • 复选列
  • 单选列
  • 序号列
  • 详情跳转列
  • 开关列
  • 图片列
  • 按钮列
  • 分隔展示
  • 拼接展示
  • 气泡提示
  • 气泡表格
  • 表头插槽
  • 单元格插槽
<template>
  <element-table
    :columns="columns"
    :main-data="tableData"
    :show-checkbox="true"
    :show-radio="true"
    :select-radio.sync="selectRadio"
    :show-index="true"
    :page="page"
    row-key="id"
    @handleButton="handleButton"
    @setStatus="setStatus"
    @openDetail="openDetail"
  />
</template>

<script>
import { ElementTable } from 'common-utils-kit/element';

export default {
  components: {
    ElementTable,
  },
};
</script>

ScrollTable

滚动加载表格组件:

<template>
  <scroll-table
    :columns="columns"
    :main-data="tableData"
    :loading="loading"
    :finished="finished"
    height="460"
    @load="loadMore"
  />
</template>

<script>
import { ScrollTable } from 'common-utils-kit/element';

export default {
  components: {
    ScrollTable,
  },
};
</script>

常用参数:

  • columns
  • mainData
  • loading
  • finished
  • loadDistance
  • height

ScreenScale

大屏缩放容器:

<template>
  <screen-scale :width="1920" :height="1080">
    <div style="width: 1920px; height: 1080px;">
      大屏内容
    </div>
  </screen-scale>
</template>

<script>
import { ScreenScale } from 'common-utils-kit/element';

export default {
  components: {
    ScreenScale,
  },
};
</script>

ResetDrawer

用于解决业务抽屉外层直接 v-if 销毁时,append-to-body 挂载异常的问题。

<template>
  <reset-drawer
    v-model="drawerVisible"
    title="业务抽屉"
    size="480px"
    :wrapper-closable="false"
  >
    <business-drawer-content :id="currentId" />
  </reset-drawer>
</template>

<script>
import { ResetDrawer } from 'common-utils-kit/element';

export default {
  components: {
    ResetDrawer,
  },
};
</script>

ResetDialog

用于解决业务弹窗外层直接 v-if 销毁时,append-to-body 挂载异常的问题。

<template>
  <reset-dialog
    v-model="dialogVisible"
    title="业务弹窗"
    width="560px"
    :close-on-click-modal="false"
  >
    <business-dialog-content :id="currentId" />
    <template slot="footer">
      <el-button @click="dialogVisible = false">取消</el-button>
      <el-button type="primary" @click="dialogVisible = false">确定</el-button>
    </template>
  </reset-dialog>
</template>

<script>
import { ResetDialog } from 'common-utils-kit/element';

export default {
  components: {
    ResetDialog,
  },
};
</script>

View3D

View3D 为三维展示组件,当前通过 common-utils-kit/element 兼容导出:

import { View3D } from 'common-utils-kit/element';

具体业务参数请结合实际页面或示例工程使用。

本地开发

npm run dev

构建

npm run build

构建 npm 主入口

npm run lib

构建 Element 子入口

npm run lib:module

发布前需要同时执行 npm run libnpm run lib:module,确保主入口 common-utils-kit 与组件入口 common-utils-kit/element 都生成对应产物。

检查

npm run lint