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

z-crud-table

v0.0.63

Published

A powerful and flexible CRUD table component for Vue 3 and Element Plus.

Readme

CrudTable - 基于 Vue 3 和 Element Plus 的高级 CRUD 组件

CrudTable 是一个功能全面、高度可定制的 CRUD 表格组件,旨在通过声明式的方式,极大地简化数据驱动的页面开发。它封装了常见的增、删、改、查、分页、批量操作等逻辑,让开发者能更专注于业务本身。

✨ 功能特性

  • API驱动: 通过 props 传入 URL 字符串,组件内置 axios 请求逻辑。
  • 高度可定制: 提供丰富的插槽,用于自定义查询条件、表格列、操作按钮等。
  • 配置驱动表单: 支持通过 JSON 数组配置动态渲染新增/编辑弹窗内的表单。
  • 完整的 el-table 功能: 继承 el-table 所有原生属性和事件,无缝衔接现有使用习惯。
  • 强大的生命周期: 提供完整的 onBeforeonAfter 钩子,方便在操作前后进行数据处理和逻辑注入。
  • 灵活的列控制: 可通过 props 单独控制多选框、序号列、操作列以及编辑/删除按钮的显示与隐藏。
  • 开箱即用: 内置了分页、单行删除、批量删除等常用功能。

📦 安装

npm install your-crud-table-package-name

🚀 快速上手

在您的 Vue 组件中使用 CrudTable

<template>
  <crud-table
    ref="crudTableRef"
    :api-url-query="'/api/users'"
    :api-url-detail="'/api/users/detail'"
    :api-url-create="'/api/users'"
    :api-url-update="'/api/users'"
    :api-url-delete="'/api/users'"
    :initial-search-form="{ pageNum: 1, pageSize: 5 }"
    :dialog-form-config="dialogFormConfig"
  >
    <el-table-column prop="name" label="姓名" />
    <el-table-column prop="email" label="邮箱" />
  </crud-table>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import CrudTable from 'your-crud-table-package-name';

const crudTableRef = ref(null);

const dialogFormConfig = ref([
  { type: 'input', prop: 'name', label: '姓名' },
  { type: 'input', prop: 'email', label: '邮箱' },
]);
</script>

API 文档

属性 (Props)

| 属性名 | 描述 | 类型 | 是否必需 | 默认值 | | --- | --- | --- | --- | --- | | API 配置 | | | | | | apiUrlQuery | 获取表格列表数据的接口地址。 | String | true | - | | apiUrlDetail | 获取单条数据详情的接口地址(用于编辑时回填表单)。 | String | true | - | | apiUrlCreate | 创建新条目的接口地址。 | String | true | - | | apiUrlUpdate | 更新条目的接口地址。 | String | true | - | | apiUrlDelete | 删除条目的接口地址。 | String | true | - | | 功能控制 | | | | | | showSelectionColumn | 是否显示表格的多选框列。 | Boolean | false | true | | showIndexColumn | 是否显示表格的序号列。 | Boolean | false | true | | showActionsColumn | 是否显示操作列。 | Boolean | false | true | | showEditButton | 是否在操作列中显示默认的“编辑”按钮。 | Boolean | false | true | | showDeleteButton | 是否在操作列中显示默认的“删除”按钮。 | Boolean | false | true | | actionsColumnWidth | 操作列的宽度。 | Number | false | 120 | | 表单与弹窗 | | | | | | dialogWidth | 新增/编辑弹窗的宽度。 | String | false | '50%' | | dialogFormConfig | 动态表单配置数组,用于快速生成弹窗内的表单。 | Array | false | [] | | dialogFormRules | 弹窗表单的 Element Plus 验证规则。 | Object | false | {} | | 分页配置 | | | | | | initialSearchForm | 查询表单的初始值,包含初始分页参数 pageNumpageSize。 | Object | false | { pageNum: 1, pageSize: 10 } | | showPagination | 是否显示分页组件。 | Boolean | false | true | | pageSizes | 每页显示个数选择器的选项设置。 | Array | false | [10, 20, 50, 100] | | paginationLayout | 分页组件布局。 | String | false | 'total, sizes, prev, pager, next, jumper' | | paginationBackground | 是否为分页按钮添加背景色。 | Boolean | false | true | | paginationSmall | 是否使用小型分页样式。 | Boolean | false | false | | paginationHideOnSinglePage | 只有一页时是否隐藏分页。 | Boolean | false | false | | 生命周期钩子 | | | | | | onBeforeQuery | 查询请求执行。可用于修改请求参数。必须返回处理后的参数对象。 | Function | false | - | | onAfterQuery | 查询请求执行。可用于格式化返回的列表数据。必须返回处理后的数据数组。 | Function | false | - | | onBeforeOpenDialog | 打开弹窗执行。可用于预处理表单数据。 | Function | false | - | | onAfterOpenDialog | 打开弹窗执行。可用于在弹窗渲染后执行某些操作。 | Function | false | - | | onBeforeSubmit | 表单提交执行。可用于序列化提交的数据。必须返回处理后的数据对象。 | Function | false | - | | onAfterSubmit | 表单提交执行。可用于执行提交成功后的副作用。 | Function | false | - | | onBeforeDelete | 删除操作执行。可用于进行额外的确认。返回 false 可中止删除。 | Function | false | - | | onAfterDelete | 删除操作执行。可用于执行删除成功后的副作用。 | Function | false | - |

插槽 (Slots)

| 插槽名称 | 作用域 (Props) | 描述 | | --- | --- | --- | | default | - | (核心) 用于定义表格的列 (<el-table-column>),除了序号列、复选框列和操作列。 | | header | - | 在整个组件最顶部插入内容,如页面大标题。 | | query-conditions | { searchForm } | 自定义查询区域的表单项。searchForm 是响应式的查询对象。 | | query-left | - | 在“搜索”按钮左侧添加自定义按钮或内容。 | | query-right | - | 在“清空”按钮右侧添加自定义按钮或内容。 | | action-left | { selections } | 在“新增”按钮左侧添加自定义按钮,可通过 selections 访问当前勾选的数据。 | | action-right | - | 在“新增”按钮右侧添加自定义按钮。 | | actions | { row } | (重要) 自定义操作列的内容,可用于添加、修改或完全替换默认的编辑/删除按钮。 | | dialog-form-content | { formData, mode } | 完全自定义新增/编辑弹窗的表单内容。如果使用此插槽,dialogFormConfig 将被忽略。 |

事件 (Events)

| 事件名称 | 载荷 (Payload) | 描述 | | --- | --- | --- | | @open-dialog | { mode: string, data: object } | 在新增或编辑弹窗打开后触发。 | | @submit | { mode: string, data: object } | 在表单提交(新增或更新)成功触发。 | | @delete | number[] | 在删除操作成功触发,载荷为被删除的 ID 数组。 |

暴露的方法 (Exposed Methods)

通过 ref 可以获取到组件实例,并调用其暴露的方法。

| 方法名称 | 参数 | 描述 | | --- | --- | --- | | refresh() | - | 强制刷新表格数据,使用当前的查询条件和分页状态。 | | search() | - | 重置到第一页并刷新数据,相当于点击“搜索”按钮。 | | handleDelete(ids: number[]) | ids (ID 数组) | 触发删除操作,可用于父组件中自定义的批量删除逻辑。 | | openDialog(mode, data) | mode, data | 手动打开新增/编辑弹窗。 |

实践案例

<template>
  <crud-table
    ref="crudTableRef"
    :api-url-query="'/api/users'"
    :api-url-detail="'/api/users/detail'"
    :api-url-create="'/api/users'"
    :api-url-update="'/api/users'"
    :api-url-delete="'/api/users'"
    :show-delete-button="false"
    actions-column-width="140"
    :initial-search-form="{ role: null, pageNum: 1, pageSize: 5 }"
    @submit="onSubmit"
    :on-after-query="handleAfterQuery"
  >
    <template #header>
      <h2 class="text-2xl font-semibold text-slate-700 mb-6">用户管理</h2>
    </template>

    <el-table-column prop="name" label="姓名" sortable />
    <el-table-column prop="role" label="角色">
        <template #default="scope">
            <el-tag :type="scope.row.role === 'admin' ? 'warning' : 'info'">
                {{ scope.row.role }}
            </el-tag>
        </template>
    </el-table-column>
    <el-table-column prop="createdAtFormatted" label="创建时间" />

    <template #query-conditions="{ searchForm }">
        <el-form-item label="姓名">
            <el-input v-model="searchForm.name" clearable />
        </el-form-item>
    </template>

    <template #actions="{ row }">
        <el-button size="small" type="primary" link @click="crudTableRef?.openDialog('edit', row)">编辑</el-button>
        <el-button size="small" type="success" link @click="handleViewDetails(row)">详情</el-button>
    </template>
  </crud-table>
</template>

<script setup>
import { ref } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import CrudTable from './components/CrudTable.vue';

const crudTableRef = ref(null);

// 使用生命周期钩子格式化数据
const handleAfterQuery = (data) => {
    return data.map(item => ({
        ...item,
        createdAtFormatted: new Date(item.createdAt).toLocaleString('zh-CN'),
    }));
};

// 监听事件
const onSubmit = (payload) => {
    ElMessage.success(`[Event] ${payload.mode} success!`);
};

// 自定义方法
const handleViewDetails = (row) => {
    ElMessageBox.alert(JSON.stringify(row, null, 2), '详情');
};
</script>