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

yudada-table

v1.0.2

Published

`YudadaTable` 是基于 **Vue3 + Element Plus** 的 `el-table` 二次封装组件,专注于「**配置化列定义** + **常用表格交互开箱即用**」:

Readme

简介

YudadaTable 是基于 Vue3 + Element Plusel-table 二次封装组件,专注于「配置化列定义 + 常用表格交互开箱即用」:

  • 完整支持:支持 el-table / el-table-column 的绝大部分属性、事件和插槽。
  • 增强多选:内置跨分页多选功能,支持选中记忆。
  • 多级表头:通过 children 字段即可配置多级列,零模板嵌套。
  • 操作列、展开行、追加行:常用表格交互能力一站式集成。
  • 分页封装:内置 el-pagination,统一管理分页状态和事件。

作者信息


安装与注册

安装

npm i YudadaTable

yarn add YudadaTable

说明YudadaTable 依赖 Element Plus,请确保你的项目中已经安装并全局引入了 Element Plus 以及它的样式文件。

# 如果还没有装过 Element Plus,需要先安装
npm i element-plus
# 或
yarn add element-plus

全局挂载组件

import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import YudadaTable from 'YudadaTable'

const app = createApp(App)

app.use(ElementPlus)
app.use(YudadaTable)

app.mount('#app')

注册完成后即可在任意页面直接使用标签 <YudadaTable />(或 <yudada-table />)。


推荐使用步骤(快速上手指引)

  1. 安装依赖,并全局注册 Element Plus + 引入其 CSS,再注册 YudadaTable 组件(见上文)。
  2. 准备表格数据 tableData:通常是接口返回的数据列表。
  3. 定义列配置 columns(核心):使用 JSON 形式定义每一列的 proplabelslotNamechildren 等。
  4. 配置表格行为 tableConfig:是否显示多选、序号列、操作列、展开行、追加尾行等。
  5. 配置分页 paginationConfig(可选):在开启分页时,统一管理 currentpageSizetotal 等字段。
  6. 在模板中引入 <YudadaTable />,通过 props 传入上述配置,并根据需要监听分页与多选等事件。

下方的「快速上手」示例即是按照以上步骤组合而成。


快速上手

<template>
  <YudadaTable
    stripe
    border
    show-summary
    :summary-method="getSummaries"
    :tableData="tableData"
    :loading="loading"
    :columns="tableColumns"
    :tableConfig="tableConfig"
    :paginationConfig="paginationConfig"
    @page-size-change="onPageSizeChange"
    @current-page-change="onCurrentPageChange"
    ref="yudadaTableRef"
  >
    <!-- 自定义列 -->
    <template #name="{ scope }">
      <el-tag type="success">{{ scope.row.name }}</el-tag>
    </template>

    <!-- 自定义操作列 -->
    <template #handler="{ scope }">
      <el-button size="small" type="primary" @click="editRow(scope.row)">编辑</el-button>
      <el-button size="small" type="danger" @click="deleteRow(scope.row)">删除</el-button>
    </template>
  </YudadaTable>
</template>

<script setup lang="js">
import { reactive, ref } from 'vue'

const loading = ref(false)

// 表格数据
const tableData = ref([])

// 列配置(重点:传 JSON)
const tableColumns = reactive([
  {
    label: '排名',
    prop: 'ranking',
    type: 'index',
    width: 80,
    index: (index) => index + 1
  },
  {
    prop: 'name',
    label: '姓名',
    slotName: 'name' // 使用插槽渲染
  }
])

// 表格基础配置
const tableConfig = reactive({
  showSeletion: true,      // 显示多选
  showIndexColumn: true,   // 显示序号列
  showHandler: true,       // 显示操作列
  isCheckMemory: true      // 跨页记忆勾选
})

// 分页配置
const paginationConfig = reactive({
  current: 1,
  pageSize: 10,
  total: 0
})

function onPageSizeChange(size) {
  paginationConfig.pageSize = size
}

function onCurrentPageChange(page) {
  paginationConfig.current = page
}

function editRow(row) {
  console.log('编辑', row)
}

function deleteRow(row) {
  console.log('删除', row)
}

const yudadaTableRef = ref()

// 自定义合计方法(示例)
function getSummaries({ columns, data }) {
  const sums = []
  columns.forEach((column, index) => {
    if (index === 0) {
      sums[index] = '合计'
      return
    }
    const values = data.map((item) => Number(item[column.property]))
    if (!values.every((value) => Number.isNaN(value))) {
      sums[index] = values.reduce((prev, curr) => {
        const value = Number(curr)
        if (!Number.isNaN(value)) {
          return prev + curr
        } else {
          return prev
        }
      }, 0)
    } else {
      sums[index] = ''
    }
  })
  return sums
}
</script>

如何传入列的 JSON(columns

columns 是一个数组,每一项对应一个 el-table-column,支持 el-table-column 的所有属性,并额外扩展:

  • slotName:自定义列内容的插槽名称(例如 slotName: 'name' 对应 <template #name>)。
  • children:子列数组,用于配置多级表头。

复杂列配置示例(节选自 examples/data.ts

export const columns = [
  {
    label: '排名',
    prop: 'ranking',
    type: 'index',
    width: 80,
    index: (index) => index * 3
  },
  {
    prop: 'name',
    label: '名字',
    filters: [
      { text: '李白2', value: '李白2' },
      { text: '李白4', value: '李白4' }
    ],
    'filter-method': (value, row, column) => {
      const property = column['property']
      return row[property] === value
    },
    slotName: 'name'
  },
  {
    prop: 'address',
    label: '地址',
    children: [
      {
        label: '省份',
        prop: 'province',
        align: 'center'
      },
      {
        label: '城市',
        prop: 'city',
        align: 'center',
        children: [
          {
            label: '区',
            prop: 'area',
            align: 'center'
          },
          {
            label: '县',
            prop: 'county',
            align: 'center'
          }
        ]
      }
    ]
  },
  {
    prop: 'amount',
    label: '金额',
    sortable: true
  }
]

在页面中直接传入:

<YudadaTable :columns="columns" />

多级表头说明:只要某一项有 children 数组,就会自动使用多级表头组件递归渲染。


如何获取表格全选/多选后的行数据

组件通过 原生事件实例方法 两种方式操作和获取多选数据。

1. 通过原生事件获取选中行

组件支持 el-table 原生的 selection-change 事件,可以通过监听该事件获取当前页的选中行:

<YudadaTable
  :tableData="tableData"
  :columns="columns"
  :tableConfig="{ showSeletion: true, isCheckMemory: true }"
  @selection-change="onSelectionChange"
/>

<script setup lang="js">
import { ref } from 'vue'

const selection = ref([])

function onSelectionChange(rows) {
  selection.value = rows
  console.log('当前选中行:', rows)
}
</script>

注意:如果需要获取跨页选中的行,可以通过监听 selection-change 事件并自行维护选中状态,或者使用 el-table 原生的 reserve-selection 属性(通过 tableConfig.isCheckMemory 配置)。

2. 通过 ref 操作多选(全选 / 取消全选)

组件内部暴露了若干方法(见下方"实例方法"),跟 el-table 的多选方法保持一致:

  • clearSelection():清空所有勾选。
  • toggleRowSelection(row, selected?):切换单行勾选。
  • toggleAllSelection():切换全选/全不选。
<template>
  <YudadaTable
    ref="xmwTableRef"
    :tableData="tableData"
    :columns="columns"
    :tableConfig="{ showSeletion: true }"
    @selection-change="onSelectionChange"
  />

  <el-button @click="clearAll">清空多选</el-button>
  <el-button @click="toggleAll">切换全选/全不选</el-button>
</template>

<script setup lang="js">
import { ref } from 'vue'

const xmwTableRef = ref()
const selection = ref([])

// 监听原生 selection-change 事件获取选中行
function onSelectionChange(rows) {
  selection.value = rows
  console.log('当前选中行:', rows)
}

function clearAll() {
  xmwTableRef.value?.clearSelection()
}

function toggleAll() {
  xmwTableRef.value?.toggleAllSelection()
}
</script>

注意:如果需要获取跨页选中的行,可以通过监听 selection-change 事件并自行维护选中状态,或者使用 el-table 原生的 reserve-selection 属性(通过 tableConfig.isCheckMemory 配置)。


如何取消合计列(合计行)

组件内部通过 v-bind="$attrs" 将属性透传给 el-table,因此合计行与 Element Plus 原生用法保持一致:

  • 开启合计:增加 show-summary 属性(或 :show-summary="true")。
  • 自定义合计规则:传入 summary-method
  • 取消合计:删除 show-summary 属性,或者设置为 false
<!-- 开启合计 -->
<YudadaTable
  :tableData="tableData"
  :columns="columns"
  show-summary
  :summary-method="getSummaries"
/>

<!-- 取消合计(两种写法任选其一) -->
<YudadaTable
  :tableData="tableData"
  :columns="columns"
/>

<YudadaTable
  :tableData="tableData"
  :columns="columns"
  :show-summary="false"
/>

Table Props(封装组件本身)

除表中列出内容外,还支持所有 el-table 原生属性(通过 $attrs 透传)。

| 参数 | 说明 | 类型 | 默认值 | | :----------------- | :---------------------------------------- | :-----: | :----: | | tableData | 表格数据 | Array | - | | columns | 列配置,详情见「Column 属性」 | Array | - | | loading | 加载状态 | Boolean | false | | tableConfig | 表格扩展配置项,详情见下方 tableConfig | Object | - | | showPagination | 是否显示分页 | Boolean | true | | paginationConfig | 分页配置项,详情见下方 paginationConfig| Object | - |


Column 属性

除下表外,支持所有 el-table-column 属性

| 参数 | 说明 | 类型 | 默认值 | | :--------- | :----------------------------- | :-------------------- | :----: | | slotName | 启用插槽渲染该列,值为插槽名称 | Boolean / String | false | | children | 多级表头子列配置 | Array<ColumnConfig> | - |


tableConfig 配置项

除下表字段外,其余字段会直接合并到内部 el-table 上。

| 参数 | 说明 | 类型 | 默认值 | | :---------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------: | :------------------------------------------: | | rowKey | 行数据的 Key,用来优化 Table 渲染;在使用多选或树形数据时必填。String 类型支持多层访问:user.info.id,不支持 user.info[0].id,此种情况请使用 Function。 | Function(row)/String | 'id' | | showSeletion | 是否支持多选 | Boolean | false | | showIndexColumn | 是否显示序号列 | Boolean | false | | indexLabel | 自定义索引列表头名 | String | '序号' | | isCheckMemory | 是否需要跨页勾选记忆 | Boolean | false | | showHandler | 是否显示操作列 | Boolean | false | | showExpand | 是否是展开行 | Boolean | false | | showAppend | 是否在表格最后一行之后插入内容(若有合计行,则在合计行之上) | Boolean | false | | appendLabel | 追加列默认显示的文字 | String | '自定义' | | handlerConfig | 操作列配置,showHandler 为 true 时有效,会与默认 { label: '操作', minWidth: 80, fixed: 'right' } 合并 | Object | { label: '操作', minWidth: 80, fixed: 'right' } |


Page(paginationConfig)配置项

除下表外,支持所有 el-pagination 属性

| 参数 | 说明 | 类型 | 默认值 | | :---------- | :--------------------- | :----: | :--------------------------------------- | | total | 条目数 | number | 0 | | current | 当前页数 | number | 1 | | pageSize | 每页显示条目个数 | number | 10 | | pageSizes | 每页显示个数选择器选项 | Array | [10, 20, 30, 50] | | layout | 分页组件布局 | String | "total, sizes, prev, pager, next, jumper" |


Slot 插槽

| name | 说明 | 参数 | | :---------------- | :------------------------------------------------------------------- | :----------------------: | | handler | 自定义操作列的内容(需 tableConfig.showHandler = true) | { scope } | | expand | 自定义展开行内容(需 tableConfig.showExpand = true) | { props } | | append | 自定义尾部追加内容(需 tableConfig.showAppend = true) | { props } | | indexHeader | 自定义序号列表头内容(需 tableConfig.showIndexColumn = true) | { scope } | | 动态列插槽 | 任意 column.slotName='xxx' 对应 <template #xxx="{ scope }" /> | { scope } |


Events 事件

除下表外,支持所有 el-table 事件(如 selection-changerow-click 等)。

| 事件名称 | 说明 | 参数 | | :-------------------- | :----------------------------------------- | :------: | | current-page-change | current 改变时触发(分页当前页改变) | 当前页 | | page-size-change | pageSize 改变时触发(每页条数改变) | 每页条数 |


表格实例方法(通过 ref 调用)

组件通过 defineExpose 暴露了内部 el-table 常用方法,可以方便地在业务中直接调用:

  • clearSelection():清空多选状态。
  • toggleRowSelection(row, selected?):切换某行的勾选状态。
  • toggleAllSelection():切换全选 / 全不选。
  • toggleRowExpansion(row, expanded?):切换某行展开状态。
  • setCurrentRow(row?):设置当前高亮行,不传参数则取消高亮。
  • clearSort():清空排序条件,恢复原始数据顺序。
  • clearFilter(columnKeys?):清空过滤条件。
  • doLayout():手动重新布局 Table。
  • sort(prop, order):手动排序,order'ascending' | 'descending' | null
<template>
  <YudadaTable
    ref="yudadaTableRef"
    :tableData="tableData"
    :columns="columns"
  />

  <el-button @click="sortAmountDesc">按金额倒序</el-button>
</template>

<script setup lang="js">
import { ref } from 'vue'

const yudadaTableRef = ref()

function sortAmountDesc() {
  yudadaTableRef.value?.sort('amount', 'descending')
}
</script>

时间列处理(时间戳 / 年月日字符串)

组件本身不会强行帮你格式化时间,而是透传 el-table-columnformatter 和插槽能力,方便你根据业务自定义“时间戳、年月日字符串”等多种格式。

推荐方式一:使用列的 formatter(只做格式化时推荐)

在业务项目中定义一个通用的时间格式化函数,例如:

// utils/date.ts
export function formatTime(value: any) {
  if (!value) return ''

  let date: Date

  // 数字或纯数字字符串,当作时间戳
  if (typeof value === 'number' || /^\d+$/.test(String(value))) {
    date = new Date(Number(value))
  } else {
    // 普通日期字符串,例如 "2024-01-01 10:20:30"
    date = new Date(value)
  }

  if (Number.isNaN(date.getTime())) return String(value)

  const pad = (n: number) => (n < 10 ? '0' + n : n)
  const y = date.getFullYear()
  const m = pad(date.getMonth() + 1)
  const d = pad(date.getDate())
  const hh = pad(date.getHours())
  const mm = pad(date.getMinutes())
  const ss = pad(date.getSeconds())

  return `${y}-${m}-${d} ${hh}:${mm}:${ss}`
}

在列配置中使用 formatter

import { formatTime } from '@/utils/date'

const columns = [
  {
    prop: 'createdAt',
    label: '创建时间',
    formatter: (_row: any, _column: any, cellValue: any) => formatTime(cellValue)
  }
]

由于 YudadaTable 内部使用了:

<el-table-column v-bind="column" />

所以这里的 formatter 会直接传递给 Element Plus 原生的 el-table-column 生效。

推荐方式二:使用插槽渲染时间列(需要复杂 DOM 时)

当你不仅要格式化时间,还要配合图标、颜色、按钮等复杂展示时,可以给列配置一个 slotName,然后在插槽中手动调用 formatTime

// 列配置
const columns = [
  {
    prop: 'createdAt',
    label: '创建时间',
    slotName: 'createdAtCol'
  }
]
<template>
  <YudadaTable :tableData="tableData" :columns="columns">
    <template #createdAtCol="{ scope }">
      <span class="time-text">{{ formatTime(scope.row.createdAt) }}</span>
      <!-- 这里可以根据业务加图标、标签等 -->
      <el-tag v-if="scope.row.isNew" type="success">新</el-tag>
    </template>
  </YudadaTable>
</template>

建议:仅做格式化时优先使用 formatter,需要复杂结构时再用插槽。两种方式都完全由业务侧控制,组件本身保持通用、无侵入。