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

@hz_yujin/vue-base-table

v1.1.17

Published

Vue 3 ProTable / ProPageTable:搜索、持久化、valueType、批量操作、骨架屏、行内编辑与移动端卡片

Readme

@hz_yujin/vue-base-table

本包位于 monorepo packages/table。仓库根目录见 README

基于 Vue 3 + TypeScript 的可复用表格组件库(VXE Table Grid),提供搜索表单与状态持久化。

  • ProPageTable — 搜索 + 表格一体化(推荐)
  • ProTable — 高级表格
  • ProSearchForm — 可折叠搜索表单

安装

npm install @hz_yujin/vue-base-table element-plus @element-plus/icons-vue vxe-table vxe-pc-ui

element-plusvxe-tablevxe-pc-ui@element-plus/icons-vuepeerDependencies,需由宿主项目安装。

注册依赖与样式

必须在入口完成依赖注册,并引入样式(缺一不可):

import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
import VxeUIBase from 'vxe-pc-ui'
import 'vxe-pc-ui/lib/style.css'
import VxeUITable from 'vxe-table'
import 'vxe-table/lib/style.css'
import zhCN from 'vxe-table/es/locale/lang/zh-CN'
import '@hz_yujin/vue-base-table/style.css'

// 按需引入组件
import { ProPageTable } from '@hz_yujin/vue-base-table'

// 或全局注册
import VueBaseTable from '@hz_yujin/vue-base-table'

const app = createApp(App)
app.use(ElementPlus, { locale: zhCn })
app.use(VxeUIBase)
app.use(VxeUITable)
// VxeUITable.setConfig({ i18n: (key, args) => ... }) // 可选:配置 VXE 中文
app.use(VueBaseTable) // 可选:全局注册 ProTable / ProPageTable / ProSearchForm
app.mount('#app')

中文项目建议同时配置 Element Plus / VXE 的 zh-CN 语言包。

ProPageTable 用法(推荐)

<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import {
  ProPageTable,
  createSearchModel,
  type ProTableColumn,
  type SearchField,
} from '@hz_yujin/vue-base-table'

interface Row {
  id: number
  name: string
  status: string
}

const searchFields: SearchField[] = [
  { key: 'keyword', label: '关键词', type: 'input', placeholder: '请输入' },
  {
    key: 'status',
    label: '状态',
    type: 'select',
    options: [
      { label: '启用', value: '启用' },
      { label: '禁用', value: '禁用' },
    ],
  },
]

const searchForm = reactive(createSearchModel(searchFields))
const columns: ProTableColumn<Row>[] = [
  { field: 'name', title: '名称', minWidth: 140, sortable: true },
  { field: 'status', title: '状态', width: 100, slot: 'status' },
  { field: 'action', title: '操作', width: 140, slot: 'action', fixed: 'right' },
]

const loading = ref(false)
const data = ref<Row[]>([])
const pagination = ref({ currentPage: 1, pageSize: 10, total: 0 })

async function loadData() {
  loading.value = true
  try {
    // 调用业务接口,写入 data / pagination.total
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  pagination.value.currentPage = 1
  loadData()
}

function handlePageChange(payload: { currentPage: number; pageSize: number }) {
  pagination.value.currentPage = payload.currentPage
  pagination.value.pageSize = payload.pageSize
  loadData()
}

onMounted(loadData)

function onSearchModelUpdate(value: Record<string, unknown>) {
  // reactive 必须就地合并,勿直接 v-model 整对象替换
  Object.assign(searchForm, value)
}
</script>

<template>
  <ProPageTable
    :search-model="searchForm"
    @update:search-model="onSearchModelUpdate"
    :search-fields="searchFields"
    :columns="columns"
    :data="data"
    :loading="loading"
    :pagination="pagination"
    row-key="id"
    selection="checkbox"
    storage-key="demo-list"
    @search="handleSearch"
    @reset="handleSearch"
    @refresh="loadData"
    @page-change="handlePageChange"
  >
    <template #toolbar-left>
      <el-button type="primary">新增</el-button>
    </template>
    <template #status="{ row }">
      <el-tag>{{ row.status }}</el-tag>
    </template>
    <template #action>
      <el-button link type="primary">编辑</el-button>
    </template>
  </ProPageTable>
</template>

更完整的 API 说明见 docs/ProPageTable.md

ProSearchForm 单独使用

<ProSearchForm
  v-model="searchForm"
  :fields="searchFields"
  @search="handleSearch"
  @reset="handleReset"
/>

SearchField 支持的 type

| type | 说明 | 默认空值 | |------|------|----------| | input | 文本输入(默认) | '' | | textarea | 多行文本 | '' | | number | 数字输入 | undefined | | select | 下拉单选 | '' | | select-multiple | 下拉多选 | [] | | date / date-range | 日期 / 日期范围 | '' / [] | | datetime / datetime-range | 日期时间 / 范围 | '' / [] | | time / time-range | 时间 / 范围 | '' / [] | | month / year | 月份 / 年份 | '' | | cascader | 级联选择 | [] | | tree-select | 树形选择 | '' | | radio / radio-button | 单选 | '' | | checkbox / checkbox-group | 复选 | false / [] | | switch | 开关 | false | | autocomplete | 自动补全 | '' | | slot | 自定义控件 | — |

未覆盖的场景可使用 type: 'slot' + #fieldKey 插槽(在 ProPageTable 上为 #search-{fieldKey})。

状态持久化

传入 storage-keypersist 后,自动将配置保存到 localStorage / sessionStorage

<ProPageTable
  :persist="{ storageKey: 'user-management' }"
  :columns="columns"
  :data="data"
  :pagination="pagination"
/>

| 持久化项 | 说明 | |----------|------| | 列显隐 / 列宽 / 列顺序 / 冻结 | VXE customConfig.storage | | 排序字段与升降序 | 自动保存与恢复 | | 表头筛选 | filters 勾选状态 | | 每页条数 | pagination.pageSize | | 搜索区展开/收起 | 折叠状态 | | 搜索条件值 | 查询/重置时写入,刷新后恢复 |

细粒度配置:

persist={{
  storageKey: 'user-list',
  storage: 'local', // 或 'session'
  column: true,
  sort: true,
  pagination: true,
  searchExpanded: true,
  search: true,
}}

清除缓存:tableRef.value?.clearPersist()

ProTable 能力一览

| 能力 | 说明 | |------|------| | 序号列 | show-seq 默认开启 | | 行选择 | selection="checkbox" / "radio",支持 reserve-selection | | 排序 / 筛选 | 列配置 sortablefilters;支持远程;筛选可持久化 | | valueType | digit / money / percent / date / datetime / tag / select | | valueEnum | 枚举文案与 Tag 状态色 | | 多级表头 | children 嵌套列 | | 尺寸 | size="small" 等 | | 空状态 | 默认插画 + emptyText;可用 #empty 自定义 | | 分页 | pagination 配置 | | 工具栏 | 刷新、列自定义、查询条件显隐;可选全屏/导出/打印 | | 树形表格 | tree-config | | 虚拟滚动 | virtual-scroll | | 远程数据 | request + proxy,或 useProTableRequest 受控封装 | | 列宽拖拽 | resizable 默认开启 | | 移动端卡片 | mobile-card 默认开启(≤768px) | | 插槽 | #columnSlot#toolbar-left#toolbar-right#empty#expand |

valueType / valueEnum 示例

{
  field: 'status',
  title: '状态',
  valueType: 'tag',
  valueEnum: {
    启用: { text: '启用', status: 'success' },
    禁用: { text: '禁用', status: 'info' },
  },
}

useProTableRequest(受控模式)

import { useProTableRequest } from '@hz_yujin/vue-base-table'

const {
  searchModel,
  searchFields,
  loading,
  data,
  pagination,
  handleSearch,
  handleReset,
  handlePageChange,
  handleSortChange,
  handleFilterChange,
  refresh,
} = useProTableRequest({
  columns,
  searchFields: [...],
  persist: { storageKey: 'user-list' },
  fetcher: async ({ currentPage, pageSize, form, sort, filters }) => {
    const res = await api.list({ currentPage, pageSize, ...form, sort, filters })
    return { list: res.list, total: res.total }
  },
})

扩展能力

组件刻意做成「可注册 + 可透传 + 多插槽」结构,业务不必 fork 源码。

1. 注册自定义 valueType

import { h } from 'vue'
import { ElProgress } from 'element-plus'
import { registerValueType } from '@hz_yujin/vue-base-table'

registerValueType('progress', {
  format: (v) => `${Number(v) * 100}%`,
  render: ({ cellValue }) =>
    h(ElProgress, { percentage: Number(cellValue) * 100, strokeWidth: 10 }),
})

// 列上使用
{ field: 'rate', title: '进度', valueType: 'progress' }

2. 注册自定义搜索控件

import { registerSearchField } from '@hz_yujin/vue-base-table'

registerSearchField('my-select', MySelectComponent)
// 控件需接受 field / modelValue,并 emit update:modelValue

{ key: 'city', label: '城市', type: 'my-select' }

3. 列 render / 插槽 / gridOptions / gridEvents

| 方式 | 说明 | |------|------| | column.render | 返回 VNode,轻量自定义单元格 | | #{field} 插槽 | 完整自定义单元格 | | gridOptions | 透传 VXE 全部配置 | | gridEvents | 透传 VXE 事件 |

4. 页面区域插槽(ProPageTable)

#before / #search / #middle / #table-header / #table-footer / #after

5. 全局 / 局部默认配置

import { setProTableDefaults, provideProTableConfig } from '@hz_yujin/vue-base-table'

setProTableDefaults({ size: 'small', emptyText: 'No Data' })

// 或在布局中
provideProTableConfig({ size: 'mini' })

// 安装时一并注册
app.use(VueBaseTable, {
  defaults: { size: 'small' },
  valueTypes: { progress: { ... } },
  searchFields: { 'my-select': MySelect },
})

主题变量

可在外层覆盖:

.pro-page-table {
  --pro-table-bg: #fff;
  --pro-table-border: #ebeef5;
  --pro-table-radius: 8px;
  --pro-table-padding: 16px;
}

移动端适配

默认开启:视口或容器宽度 ≤ 768px 时切换为卡片列表。

<!-- 关闭 -->
<ProPageTable :mobile-card="false" ... />

<!-- 自定义 -->
<ProPageTable
  :mobile-card="{ breakpoint: 992, titleField: 'username', maxFields: 6 }"
  ...
/>

列级:cardTitle / cardHidden / cardAction

本地开发

npm run dev

构建组件库

npm run build:lib

产物:dist/index.jsdist/index.d.tsdist/index.css

License

MIT