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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@skb_skb/kb-components

v1.0.38

Published

通用组件库,包含 Element UI 扩展和 UniApp 组件

Readme

kb-components

一个基于Vue.js的通用组件库,提供丰富的UI组件、工具方法和指令,适用于Vue 2项目开发。

特性

  • 提供多种实用的自定义指令(滚动处理、拖拽等)
  • 丰富的工具函数库(验证、格式化、防抖节流等)
  • 常用混入方法(验证码、表格分页、下拉刷新等)
  • 支持Element UI组件扩展
  • 支持uni-app组件
  • 易于集成和使用

快速开始

安装

npm i @skb_skb/kb-components

引入

在main.js中全局引入:

import Vue from 'vue'
import KbComponents from '@skb_skb/kb-components'

Vue.use(KbComponents)

核心功能

1. 自定义指令

v-wheelX

用于将竖向滚动转换为横向滚动,适用于横向滚动数据列表。

<div v-wheelX>
  <!-- 横向滚动内容 -->
</div>

v-loadmore

用于滚动分页场景,传入加载更多的回调函数。

<div v-loadmore="loadMoreData">
  <!-- 滚动加载内容 -->
</div>

<script>
export default {
  methods: {
    loadMoreData() {
      // 加载更多数据的逻辑
    }
  }
}
</script>

v-draggable

用于实现元素拖拽功能。

<div v-draggable>
  <!-- 可拖拽元素 -->
</div>

2. 工具方法

可以局部引入工具方法:

import { tool } from '@skb_skb/kb-components'

字典查询

// 根据字典查询对应value/label
const result = tool.getValueOrLabelFromDict({
  label: '', // 可选,若未传入value,根据传入label找到对应value
  value: '', // 可选,根据value找到对应label
  valueField: 'value',  // 字典对象中value对应字段,默认为value
  labelField: 'label', // 字典对象中label对应字段,默认为label
  list: [],  // 字典列表
  emptyText: '' // 如果未查找到对应值,返回的默认文本,默认为空字符串
})

数据验证

// 判断身份证号格式是否正确
tool.isIdCard(str)

// 判断手机号是否正确
tool.isPhone(str)

// 判断座机是否正确
tool.isLandline(str)

// 判断邮箱是否正确
tool.isEmail(str)

// 判断URL是否正确
tool.isURL(str)

// 返回小写变量类型
tool.returnType(data)

日期和时间

// 根据生日计算年龄
tool.calcAgeByBrithday(birthday)

// 日期格式化
tool.dateFormat(date, format = 'yyyy-MM-dd')

函数节流和防抖

// 防抖:在最后一次触发后延迟指定时间执行函数
const debouncedFunc = tool.debounce(func, wait)

debouncedFunc() // 调用防抖函数

// 节流:指定时间间隔内只执行一次函数
const throttledFunc = tool.throttle(func, wait, hasDebounce = false)

throttledFunc() // 调用节流函数
// hasDebounce为true时,结合防抖,停止触发后会额外执行一次

3. 混入方法

可以局部引入混入方法:

import { mixins } from '@skb_skb/kb-components'

发送验证码混入

export default {
  mixins: [mixins.sendCodeMixins],
  methods: {
    sendCode() {
      // 发送验证码逻辑
      this.startNumberDown(60) // 开始60秒倒计时
    }
  }
}

提供的属性和方法:

  • this.startNumberDown(num): 开始倒计时,传入倒计时时间
  • this.btnDisabled: 发送验证码按钮禁用状态
  • this.btnText: 发送验证码按钮文字
  • this.time: 倒计时时间
  • this.timer: 定时器ID

表格分页混入

export default {
  mixins: [mixins.tableMixins],
  methods: {
    fetch() {
      // 重写fetch方法,实现列表数据请求逻辑
      this.tableLoading = true
      // 请求数据...
      this.tableLoading = false
    }
  }
}

提供的属性和方法:

  • this.pages.size: 页大小
  • this.pages.current: 当前页
  • this.pages.total: 总计
  • this.tableList: 列表数据
  • this.tableLoading: 列表加载状态
  • this.fetch(): 需要自己重新定义请求分页列表方法
  • this.searchFetch(): 请求第一页
  • this.handleSizeChange(size): 页大小改变
  • this.handleCurrentChange(page): 当前页改变

下拉刷新混入

export default {
  mixins: [mixins.pullRefreshMixins],
  methods: {
    fetch() {
      // 重写fetch方法,实现列表数据请求逻辑
      // 请求数据...
      this.handlePageResult(res)
    }
  }
}

提供的属性和方法:

  • this.search.size: 页大小
  • this.search.current: 当前页
  • this.search.total: 总计
  • this.tableList: 列表数据
  • this.loading: 列表加载状态
  • this.finished: 全部加载完成
  • this.refreshing: 上拉刷新状态
  • this.finishedText: 加载完成文案
  • this.isEmpty: 是否为空
  • this.fetch(): 需要自己重新定义请求分页列表方法
  • this.onRefresh(): 下拉刷新
  • this.handleLoadMore(): 上拉加载更多
  • this.handlePageResult(): 请求结果处理
  • onPullDownRefresh: 小程序监听下拉刷新生命周期
  • onReachBottom: 小程序监听触底生命周期

uni-app组件

在pages.json中配置easycom:

{
  "easycom": {
    "autoscan": true,
    "custom": {
      "^fe-(.*)": "kb-components/uniapp/fe-$1/fe-$1.vue"
    }
  }
}

fe-addr-picker 地址选择组件

<fe-addr-picker 
  ref="addr"
  @change="handleAddrChange"
  @cancel="dialogShow = false"
  :requireAddrMethod="requireAddrMethod"
  :maxLevel="4"
></fe-addr-picker>

<script>
export default {
  methods: {
    initAddrPicker() {
      this.$refs.addr.init(selectAddrIds); // selectAddrIds默认选中地址id列表
    },
    requireAddrMethod() {
      // 请求收货地址列表方法
    },
    handleAddrChange(selected) {
      // 处理选择结果
    }
  }
}
</script>

属性说明:

  • maxLevel: 地址级数,省1/市2/区3/街道4,默认3级,最大4级
  • requireAddrMethod: 请求收货地址列表方法
  • 事件
    • @cancel: 取消事件
    • @change: 确定事件

fe-cutdown 倒计时组件

<fe-cutdown 
  :endTime="endTime"
  class="fz-12 c-dark"
  bgColor="transparent"
  color="var(--fe-content-color)"
  @finish="handleFinish"
></fe-cutdown>

属性说明:

  • endTime: 结束时间
  • separator: 时间间隔符,默认:
  • bgColor: 文字背景颜色,默认transparent
  • color: 文字颜色,默认#000
  • 事件
    • @finish: 倒计时结束事件

fe-fixed-btn 底部悬浮按钮

<!-- 最外层容器增加class="has-fixed-btn" -->
<div class="has-fixed-btn">
  <!-- 页面内容 -->
  <fe-fixed-btn></fe-fixed-btn>
</div>

fe-fixed-tabs 顶部悬浮选项卡

<!-- 最外层容器增加class="has-fixed-tab" -->
<div class="has-fixed-tab">
  <fe-fixed-tabs 
    v-model="type"
    :list="tabList"
    @input="handleTabChange"
  ></fe-fixed-tabs>
  <!-- 页面内容 -->
</div>

属性说明:

  • v-model: 选中的值
  • border: 是否有下边框,默认有
  • activeColor: 选中颜色
  • inactiveColor: 未选中颜色
  • list: 选项列表,格式 [{value:'',label:""}]
  • 事件
    • @input: 选中值变化事件

fe-empty 空组件

<fe-empty 
  :icon="customIcon"
  :message="'暂无数据'"
  :size="100"
>
  <!-- 额外内容插槽 -->
  <template v-slot:default>
    <button>添加数据</button>
  </template>
  <!-- 自定义图片插槽 -->
  <template v-slot:image>
    <img src="custom-img.png" />
  </template>
  <!-- 自定义描述插槽 -->
  <template v-slot:description>
    <span>暂无相关数据</span>
  </template>
</fe-empty>

属性说明:

  • icon: 图片链接
  • message: 提示文案
  • size: 图片大小

fe-modal 模态窗

<fe-modal 
  v-model="dialogShow"
  position="bottom"
  title="选择收货地址"
  :showClose="true"
  :closeOnClickOverlay="true"
>
  <!-- 模态窗内容 -->
</fe-modal>

属性说明:

  • v-model/value: 控制显示隐藏
  • closeOnClickOverlay: 点击空白处背景是否关闭,默认false
  • showTitle: 是否展示标题,默认true
  • showClose: 点击展示关闭按钮,默认true
  • showCancel: 是否展示取消按钮,默认true
  • showBtn: 是否展示下方按钮,默认true
  • custom: 是否自定义弹窗,默认false
  • width: 宽度,默认0
  • height: 高度,默认0
  • title: 弹窗标题,默认"温馨提示"
  • cancelText: 取消按钮文案,默认"取消"
  • confirmText: 确定按钮文案,默认"确定"
  • confirmLoading: 确定按钮加载状态,加载状态按钮禁用,默认false
  • position: 弹窗位置,默认"center",可选 "center" "bottom" "right"
  • 事件
    • @confirm: 点击确定按钮事件
    • @cancel: 点击取消按钮事件
    • @close: 弹窗关闭事件

fe-navbar 自定义标题栏

<fe-navbar 
  :show-home="showHome"
  title="页面标题"
  @home="handleHome"
  @back="handleBack"
></fe-navbar>

属性说明:

  • title: 标题
  • showBack: 是否展示返回按钮,默认true
  • showHome: 是否展示返回首页按钮,默认false
  • background: 背景色,默认#fff
  • 事件
    • @back: 返回上一页事件
    • @home: 返回首页事件

fe-sku 规格组件

<fe-sku 
  v-model="localSkuId"
  :defaultOptions="defaultOptions"
  ref="sku"
  @change="handleSkuChange"
></fe-sku>

<script>
export default {
  data() {
    return {
      localSkuId: '',
      defaultOptions: {
        id: 'skuId', // id
        name: 'skuName', // 名称
        price: 'price', // 价格
        stock_num: 'stocks', // 库存
        prop: 'properties' // 规格属性
      }
    }
  },
  mounted() {
    // 初始化规格数据
    this.$refs.sku.init(this.skuList);
  },
  methods: {
    handleSkuChange(sku) {
      // 处理规格变更
    }
  }
}
</script>

属性说明:

  • v-model/value: 当前skuId
  • defaultOptions: 规格对象字段配置
  • 事件
    • @change: 当前选中sku变更事件

Element UI组件

CommonSearch 搜索栏组件

import CommonSearch from 'kb-components/element/common-search'

export default {
  components: {
    CommonSearch
  }
}
<common-search 
  :labelWidth="100"
  :search="search"
  @search="handleSearch"
  @reset="handleReset"
></common-search>

属性说明:

  • labelWidth: label宽度,传入数字,默认60
  • isRow: 是否使用栅格布局24格,默认false
  • actionColSpan: 按钮在栅格布局中所占比例
  • search: 搜索配置列表,格式如下:
search: [
  {
    label: '科室', 
    type: 'select', // 搜索类型 select/input/date/cascader/radio/numberRange/pageSelect
    name: 'deptId', // 搜索key
    default: '', // 默认值,重置时恢复到默认值
    placeholder: '请选择科室', 
    span: 6, // 栅格布局中占用格数
    immediately: false, // change时是否立即触发查询
    clearable: false, // 是否展示清空内容按钮,默认true
    extraData: {}, // type为pageSelect时分页方法额外的参数
    requestMethod: function() {}, // type为pageSelect时传入分页请求方法
    options: [{label:"",value:""}], // 可选项,type为select/cascader/radio需传入该数据
    defaultProps: {
      // 除日期组件外字段
      multiple: false,
      emitPath: false,
      label: 'label',
      value: 'value',
      // 日期组件使用字段
      valueFormat: 'yyyy-MM-dd',
      type: 'daterange',
      startPlaceholder: '开始日期',
      endPlaceholder: '结束日期',
      placeholder: '请选择日期',
      pickerOptions: {}
    }
  }
]

事件:

  • @search: 搜索事件
  • @reset: 重置事件

DialogContainer 模态框组件

import DialogContainer from 'kb-components/element/dialog-container'

export default {
  components: {
    DialogContainer
  }
}
<dialog-container 
  :type="2"
  :visible.sync="dialogShow"
  title="弹窗标题"
  :showFooter="true"
>
  <!-- 弹窗内容 -->
  <template v-slot:footer>
    <!-- 自定义页尾 -->
  </template>
</dialog-container>

属性说明:

  • title: 标题
  • visible.sync: 显示隐藏双向绑定
  • width: 宽度,默认30%
  • showFooter: 是否展示页尾,默认false
  • type: 弹窗类型,1-dialog/2-drawer,默认1

插槽:

  • default: 弹窗内容插槽
  • footer: 页尾插槽

MyEchart ECharts组件

import MyEchart from 'kb-components/element/my-echart'

export default {
  components: {
    MyEchart
  },
  mounted() {
    // 初始化图表
    const option = {
      // ECharts配置项
    }
    this.$refs.bar.init(option)
  }
}
<my-echart ref="bar"></my-echart>

注意: 需要在main.js中引入echarts

import echarts from 'echarts'

PreviewPrint 打印预览组件

import PreviewPrint from 'kb-components/element/preview-print'

export default {
  components: {
    PreviewPrint
  }
}
<PreviewPrint 
  v-model="recipeDialogShow"
  printId="recipePrint"
  :url="printPDFUrl"
  @print="handleRecipePrint"
>
  <!-- 预览/打印内容插槽 -->
</PreviewPrint>

属性说明:

  • url: 预览pdf链接
  • printId: 指定预览的id,要求唯一,默认 "print"
  • value/v-model: 显示隐藏

注意: 需要在main.js中引入 vue-print-nb

import Print from 'vue-print-nb'
Vue.use(Print)

TableContainer 分页列表容器组件

import TableContainer from 'kb-components/element/table-container'

export default {
  components: {
    TableContainer
  }
}
<table-container 
  v-bind="pages"
  @current="handleCurrentChange"
  @size="handleSizeChange"
></table-container>

属性说明:

  • layout: 分页操作栏配置,默认 "total, sizes, prev, pager, next, jumper"
  • total: 分页总计
  • current: 当前页
  • size: 页大小
  • pagesSizes: 页大小可选项,默认 [10,20,50,100]

事件:

  • @current: 当前页变更事件,传参当前页码
  • @size: 页大小变更事件,传参当前页大小

WheelxTableBox el-table横向滚动容器

import WheelxTableBox from 'kb-components/element/wheelx-table-box'

export default {
  components: {
    WheelxTableBox
  }
}
<wheelx-table-box 
  :left="leftLength"
  ref="timeBox"
>
  <!-- el-table或其他需要横向滚动的内容 -->
</wheelx-table-box>

属性说明:

  • left: 初始左偏移量,默认0

注意: 需注册v-wheelX指令

MyEditor 富文本编辑器

import MyEditor from 'kb-components/element/my-editor'

export default {
  components: {
    MyEditor
  },
  methods: {
    ossUpload(file) {
      // 文件上传方法
      return new Promise((resolve, reject) => {
        // 上传逻辑
        // resolve({path: '相对路径', fullPath: '完整路径'})
      })
    }
  }
}
<MyEditor 
  ref="editor"
  v-model="formData.eduContent"
  :cache="false"
  :upload-method="ossUpload"
></MyEditor>

属性说明:

  • value/v-model: 文本内容
  • cache: 是否缓存内容
  • upload-method: 文件上传方法,promise,入参 {raw 文件二进制流,size 文件大小,name 文件名称},出参 {path 相对路径,fullPath 完整路径}

开发指南

打包

npm run package

发布

npm publish --access public

浏览器兼容性

  • Chrome (推荐)
  • Firefox
  • Safari
  • Edge
  • IE 11 (部分功能可能受限)

注意事项

  1. 本组件库基于Vue 2开发,不兼容Vue 3
  2. 使用Element UI相关组件前,请确保已正确引入Element UI
  3. 使用uni-app组件前,请确保项目环境为uni-app
  4. 部分组件需要额外的依赖支持,请参考各组件的说明文档

License

MIT