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

@stoly/vue-component

v0.1.0

Published

ant-design-vue 4.x 组件封装

Readme

@stoly/vue-component

基于 ant-design-vue 4.x 封装的 Vue 3 业务组件库,提供表格查询、弹窗、Excel 导出等开箱即用的能力。

安装

pnpm add @stoly/vue-component

开发(本仓库)

pnpm install
pnpm dev
pnpm build
pnpm lint

安装 Agent Skill

本库附带 Agent Skill,安装后 AI 编码助手(Cursor / Claude Code 等)能自动获得组件用法指引。

# 安装到当前项目(需先 pnpm add @stoly/vue-component)
pnpm dlx skills add ./node_modules/@stoly/vue-component

# 全局安装(跨项目可用)
pnpm dlx skills add ./node_modules/@stoly/vue-component -g

样式

引入组件时会自动加载样式(index.js 顶部含 import './index.css',由消费方打包工具解析):

import { VcTable, VcTableForm, VcModal } from '@stoly/vue-component'

若需手动控制样式加载,可额外使用:

import '@stoly/vue-component/style.css'

Peer Dependencies

请确保项目中已安装以下依赖:

{
  "@ant-design/icons-vue": ">=7.0.0",
  "@vueuse/core": ">=10",
  "ant-design-vue": "4.2.6",
  "vue": ">=3.2.0",
  "lodash-es": ">=4.17.21",
  "copy-to-clipboard": "^3.3.3",
  "exceljs": "^4.4.0",
  "scroll-into-view-if-needed": "^3.1.0"
}

快速开始

一个典型的「表格查询 + 弹窗」页面:

<script setup lang="ts">
import { App, Flex, Form, Input } from 'ant-design-vue'
import type { ColumnsType } from 'ant-design-vue/es/table'
import {
  VcModal,
  VcTable,
  VcTableForm,
  type VcBaseResult,
  type VcConfirmOptions,
  type VcQueryData,
} from '@stoly/vue-component'

interface Query extends VcQueryData {
  name?: string
}

interface Row {
  id: number
  name: string
}

const query = VcTableForm.useQuery<Query>()
const controller = VcTableForm.useController()
const modal = VcModal.useModal<{ id: number; name: string }>()

const columns: ColumnsType<Row> = [
  { title: '姓名', dataIndex: 'name', key: 'name' },
  {
    ...VcTable.OperateColumnProps,
    key: 'operate',
  },
]

const fetchList = async (params: Query): Promise<VcBaseResult<{ list: Row[]; total: number }>> => {
  // ...
  return { success: true, data: { list: [], total: 0 } }
}

const deleteApi = async (id: number) => {
  // ...
  return { success: true }
}
</script>

<template>
  <App>
    <VcTableForm :controller="controller" :query="query" layout="inline">
      <Flex :gap="16" wrap="wrap">
        <Form.Item label="姓名" name="name">
          <Input v-model:value="query.formState.name" placeholder="按姓名查询" allow-clear />
        </Form.Item>
      </Flex>
    </VcTableForm>

    <VcTable
      :query="query"
      :api="fetchList"
      :query-format="(q) => q"
      :data-format="(res) => ({ rows: res.data?.list ?? [], total: res.data?.total ?? 0 })"
      :columns="columns"
      show-index
      row-key="id"
    >
      <template #bodyCell="{ column, record }">
        <template v-if="column.key === 'operate'">
          <a @click="modal.open({ id: record.id, name: record.name })">查看</a>
          <a
            @click="
              VcModal.confirm(
                { api: deleteApi, params: record.id, query } satisfies VcConfirmOptions<number, VcBaseResult<unknown>>,
              )
            "
          >
            删除
          </a>
        </template>
      </template>
    </VcTable>

    <VcModal
      :title="`详情 - ${modal.params?.name ?? ''}`"
      :open="modal.visible"
      full-screen-modal
      @cancel="modal.close"
      @ok="modal.close"
    >
      <p>当前选中:{{ modal.params }}</p>
    </VcModal>
  </App>
</template>

组件

VcTable 数据表格

对 ant-design-vue Table 的增强封装,集成数据请求、分页、排序、右键菜单、列配置、密度切换等功能。

Props

继承 ant-design-vue TableProps<T>(移除 dataSource / loading / components / onChange / rowSelection

| 属性 | 类型 | 必传 | 说明 | |------|------|:----:|------| | query | SearchQuery<Q> | ✅ | 查询条件,由 VcTableForm.useQuery 创建 | | api | (params: P) => Promise<BaseResult<R>> | ✅ | 数据请求接口 | | queryFormat | (q: Q) => P | ✅ | 查询条件 → 接口参数 | | dataFormat | (res) => { rows, total } | ✅ | 接口返回值 → 表格数据 | | showIndex | boolean \| ColumnType<T> | - | 显示序号列(可自定义列配置) | | exported | boolean | - | 启用右键导出 Excel(仅适用于简单表头) | | onSelectedRows | (rows: T[]) => void | - | 传入则启用行选择,翻页/查询会清空选择 |

Ref

const tableRef = ref<VcTableInstance>()
const titles = tableRef.value?.getColumns() // 当前展示列的 title 数组

静态属性

  • VcTable.OperateColumnProps — 操作列默认配置:{ align: 'center', title: '操作', width: 120, fixed: 'right', className: 'noCopy' }
  • VcTable.Context — 通过 slot 获取当前表格 { rows, total }

列声明

支持 columns 数组,或通过 default slot 声明列(与 ant-design-vue convertChildrenToColumns 一致),配合 #bodyCell 自定义单元格。

内置功能

  • 右键菜单:刷新、复制单元格、复制行、导出行/导出当前页(需开启 exported
  • 列配置:齿轮按钮切换列可见性、拖拽排序
  • 密度切换:默认 / 紧凑
  • 回到顶部:滚动超过 100px 时显示

VcTableForm 查询表单

VcTable 配合使用的查询表单,自动管理查询/重置/分页逻辑。

Props

继承 ant-design-vue FormProps(移除内置 form 绑定方式,由组件接管 model

| 属性 | 类型 | 必传 | 说明 | |------|------|:----:|------| | query | SearchQuery<T> | ✅ | 查询条件 | | controller | TableFormController | ✅ | 表单控制器 | | defaultShowMore | boolean | - | 默认展开更多筛选 |

插槽

  • default — 表单项
  • customButtons — 替换默认查询/重置按钮
  • extra — 按钮区额外内容

静态方法

const query = VcTableForm.useQuery<Query>(initValues?)
const controller = VcTableForm.useController()

controller.submit()
controller.clear(fields?)

formState 绑定

useQuery 返回的 query.formState 为响应式对象,表单项可直接 v-model:value="query.formState.xxx",无需额外维护本地 state。

自动展开/收起

当表单内容高度超过一行时,自动出现「高级筛选」展开/收起按钮。


VcModal 可拖拽弹窗

对 ant-design-vue Modal 的增强,支持拖拽标题栏移动和全屏切换。

Props

继承 ModalProps(移除 modalRender / wrapClassName / visible

| 属性 | 类型 | 必传 | 说明 | |------|------|:----:|------| | fullScreenModal | boolean | - | 显示全屏/退出全屏按钮 | | autoFullScreen | boolean | - | 默认以全屏打开 |

事件

| 事件 | 说明 | |------|------| | fullScreenChange | 全屏状态变化,模板:@full-screen-change |

VcModal.useModal

const modal = VcModal.useModal<{ id: number }>()

modal.open({ id: 1 })
modal.close()
modal.visible  // 是否可见
modal.params   // 当前参数

VcModal.confirm

确认操作弹窗,内置成功提示和表格刷新逻辑:

// 推荐:对象参数形式
VcModal.confirm(
  {
    api: deleteUser,
    params: { id: record.id },
    query,
    tableData: { rows, total },
    callback: (res) => {},
  },
  {
    title: '删除',
    content: '确认删除该用户?',
  },
)

// 兼容:多参数形式
VcModal.confirm(deleteUser, { id: record.id }, query)
VcModal.confirm(deleteUser, { id: record.id }, (res) => {})

类型 VcConfirmOptions<P, R> 可用于 satisfies 或变量注解。

弹窗页面 Props

interface VcModalProps<P = unknown> {
  modal: ModalInstance<P>  // { visible, params, open, close }
  query?: SearchQuery<QueryData>
}

工具

VcExcel

Excel 导出工具,基于 exceljs(动态导入,不影响首屏加载)。

import { VcExcel, type VcExcelData } from '@stoly/vue-component'

await VcExcel.export(
  {
    header: [
      { header: '姓名', key: 'name', width: 10 },
      { header: '年龄', key: 'age' },
    ],
    data: [{ name: '张三', age: 28 }],
  },
  '用户列表',
)

VcExcel.downloadExcel(blob, '文件名')

VcExcel.exportasync,返回 Promise<void>


类型导出

import type {
  VcBaseResult,
  VcBaseResultData,
  VcCacheColumn,
  VcConfirmOptions,
  VcDataFormat,
  VcListPager,
  VcQueryData,
  VcSearchQuery,
  VcSort,
  VcTableFormController,
  VcTableProps,
  VcTableInstance,
  VcTableFormProps,
  VcModalProps,
  FullScreenModalProps,
  VcExcelData,
} from '@stoly/vue-component'

与 @stoly/react-component 的差异

| 能力 | React (Rc*) | Vue (Vc*) | |------|---------------|-------------| | 布局组件 | RcLayoutHeader / RcLayoutSider / RcLayoutTabPage | 暂无 | | 通用 Hooks | useSimpleReducer 等 | 暂无 | | Modal 可见性 | modal.visable | modal.visible | | 全屏回调 | prop onFullScreenChange | emit fullScreenChange | | 表格 ref | getCurrentData() | getColumns() | | 行选择 | antd rowSelection | onSelectedRows 回调 | | 查询表单绑定 | Form.Item name | query.formState + v-model |

注意事项

  1. 所有接口返回值必须包含 success: boolean 字段
  2. VcTableexported 仅适用于简单表头,复杂嵌套表头请直接调用 VcExcel.export()
  3. VcModal.confirm 传入 tableData 时会自动处理「删除最后一条数据后翻页到上一页」
  4. VcTable 不支持多字段排序,多列排序会提示错误
  5. 使用 VcTable / VcTableForm 时建议在根节点包裹 ant-design-vue 的 App 组件以正确消费 message 等上下文

License

ISC