simple-virtual-table
v0.2.0
Published
一个基于 Vue 3 的轻量级虚拟表格组件,专为高性能展示大量数据而设计
Readme
SimpleVirtualTable
一个基于 Vue 3 的轻量级虚拟表格组件,专为高性能展示大量数据而设计。支持虚拟滚动、行列固定、自定义单元格等功能。
✨ 特性
- 🚀 高性能虚拟滚动 - 仅渲染可视区域,支持 10,000+ 行数据流畅展示
- 📌 固定列支持 - 可固定第一列,便于查看行标识
- 🎨 高度可定制 - 支持自定义单元格内容、样式和交互
- 🖱️ 交互体验 - 鼠标悬停高亮、单元格点击事件
- 📱 响应式设计 - 自适应容器尺寸变化
- 🛠️ TypeScript 友好 - 完整的类型定义支持
- 🎯 Vue 3 + Composition API - 现代化的 Vue 3 开发体验
📦 安装
npm install simple-virtual-tableyarn add simple-virtual-tablepnpm add simple-virtual-table🚀 快速开始
全局注册
import { createApp } from 'vue'
import SimpleVirtualTable from 'simple-virtual-table'
import App from './App.vue'
const app = createApp(App)
app.use(SimpleVirtualTable)
app.mount('#app')局部引入
<template>
<SimpleVirtualTable
:menus="columns"
:data-map="tableData"
:row-height="40"
:column-width="120"
:is-highlight="true"
:is-fixed-first="true"
@cell-click="handleCellClick"
>
<template #cell="{ cell, rowIndex, colIndex }">
<span>{{ cell.value }}</span>
</template>
</SimpleVirtualTable>
</template>
<script setup>
import SimpleVirtualTable from 'simple-virtual-table'
// 列配置
const columns = [
{ id: 1, name: '姓名' },
{ id: 2, name: '年龄' },
{ id: 3, name: '职业' },
{ id: 4, name: '城市' }
]
// 表格数据
const tableData = [
[
{ value: '张三' },
{ value: 25 },
{ value: '工程师' },
{ value: '北京' }
],
[
{ value: '李四' },
{ value: 30 },
{ value: '设计师' },
{ value: '上海' }
]
// ... 更多数据
]
// 单元格点击事件
const handleCellClick = ({ cell, rowIndex, colIndex }) => {
console.log('点击单元格:', { cell, rowIndex, colIndex })
}
</script>📖 API 文档
Props
| 属性名 | 类型 | 默认值 | 说明 |
|--------|------|--------|------|
| menus | Array | [] | 列配置数组,每项包含 id 和 name 属性 |
| dataMap | Array | [] | 表格数据,二维数组,每个单元格为 { value } 对象 |
| rowHeight | Number | 40 | 行高度(像素) |
| columnWidth | Number | 120 | 列宽度(像素) |
| firstColumnWidth | Number | 150 | 第一列宽度(像素),仅在 isFixedFirst 为 true 时生效 |
| isHighlight | Boolean | false | 是否启用鼠标悬停高亮效果 |
| isFixedFirst | Boolean | true | 是否固定第一列 |
Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| cell-click | { cell, rowIndex, colIndex } | 单元格点击事件 |
Slots
| 插槽名 | 作用域插槽参数 | 说明 |
|--------|----------------|------|
| cell | { cell, rowIndex, colIndex } | 自定义单元格内容 |
Methods
通过 ref 可以调用以下方法:
| 方法名 | 参数 | 说明 |
|--------|------|------|
| scrollToTop | - | 滚动到顶部 |
| scrollToLeft | - | 滚动到最左侧 |
| scrollToPosition | (top, left) | 滚动到指定位置 |
🎯 使用示例
基础用法
<template>
<div style="height: 400px;">
<SimpleVirtualTable
:menus="columns"
:data-map="data"
:row-height="40"
:column-width="120"
/>
</div>
</template>
<script setup>
import { ref } from 'vue'
import SimpleVirtualTable from 'simple-virtual-table'
const columns = ref([
{ id: 1, name: 'ID' },
{ id: 2, name: '姓名' },
{ id: 3, name: '邮箱' }
])
const data = ref([
[{ value: '001' }, { value: '张三' }, { value: '[email protected]' }],
[{ value: '002' }, { value: '李四' }, { value: '[email protected]' }]
])
</script>自定义单元格
<template>
<SimpleVirtualTable
:menus="columns"
:data-map="data"
@cell-click="handleCellClick"
>
<template #cell="{ cell, rowIndex, colIndex }">
<div v-if="colIndex === 2" class="status-cell">
<span :class="getStatusClass(cell.value)">{{ cell.value }}</span>
</div>
<div v-else-if="typeof cell.value === 'number'" class="number-cell">
{{ cell.value.toLocaleString() }}
</div>
<div v-else>
{{ cell.value }}
</div>
</template>
</SimpleVirtualTable>
</template>
<script setup>
const getStatusClass = (status) => {
const statusMap = {
'正常': 'status-success',
'警告': 'status-warning',
'错误': 'status-error'
}
return statusMap[status] || 'status-default'
}
const handleCellClick = ({ cell, rowIndex, colIndex }) => {
console.log(`点击了第 ${rowIndex + 1} 行,第 ${colIndex + 1} 列:`, cell.value)
}
</script>
<style scoped>
.status-success { color: #52c41a; }
.status-warning { color: #faad14; }
.status-error { color: #f5222d; }
.number-cell { font-family: 'Monaco', monospace; }
</style>大数据量展示
<template>
<div>
<div class="controls">
<button @click="generateLargeData">生成 10,000 行数据</button>
<span>当前数据量:{{ data.length.toLocaleString() }} 行</span>
</div>
<div style="height: 500px; margin-top: 20px;">
<SimpleVirtualTable
ref="tableRef"
:menus="columns"
:data-map="data"
:is-highlight="true"
:is-fixed-first="true"
/>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const tableRef = ref()
const data = ref([])
const columns = [
{ id: 1, name: 'ID' },
{ id: 2, name: '姓名' },
{ id: 3, name: '部门' },
{ id: 4, name: '薪资' },
{ id: 5, name: '入职日期' }
]
const generateLargeData = () => {
const newData = []
for (let i = 0; i < 10000; i++) {
newData.push([
{ value: `${i + 1}` },
{ value: `员工${i + 1}` },
{ value: `部门${(i % 10) + 1}` },
{ value: Math.floor(Math.random() * 50000) + 5000 },
{ value: new Date(Date.now() - Math.random() * 365 * 24 * 60 * 60 * 1000).toLocaleDateString() }
])
}
data.value = newData
// 滚动到顶部
tableRef.value?.scrollToTop()
}
</script>🏗️ 开发
环境要求
- Node.js >= 14.x
- Vue 3.x
本地开发
# 克隆项目
git clone <repository-url>
cd simple-virtual-table
# 安装依赖
npm install
# 启动开发服务器
npm run serve
# 构建组件库
npm run lib
# 代码检查
npm run lint项目结构
simple-virtual-table/
├── packages/ # 组件源码
│ ├── index.js # 组件库入口
│ └── table/
│ ├── SimpleVirtualTable.vue # 主组件
│ └── index.js # 组件导出
├── examples/ # 示例和测试
│ ├── main.js # 示例入口
│ ├── App.vue # 示例应用
│ └── components/
│ └── virtual-table-demo.vue # 组件演示
├── public/ # 静态资源
├── vue.config.js # Vue CLI 配置
└── package.json # 项目配置🎨 自定义样式
组件使用 CSS 变量,可以方便地自定义样式:
.simple-virtual-table {
--header-bg-color: #f5f5f5;
--header-text-color: #333;
--border-color: #e0e0e0;
--hover-bg-color: #f9f9f9;
--highlight-bg-color: #e3f2fd;
--highlight-text-color: #1976d2;
}⚡ 性能特性
- 虚拟滚动技术:只渲染可视区域内的表格行,大幅减少 DOM 节点数量
- 高效的数据更新:基于 Vue 3 的响应式系统,精确更新变化的部分
- 优化的事件处理:防抖和节流优化,避免频繁的计算
- 内存友好:自动回收不可见的 DOM 元素,控制内存使用
🤝 贡献
欢迎提交 Pull Request 和 Issue!
- Fork 本仓库
- 创建你的特性分支 (
git checkout -b feature/AmazingFeature) - 提交你的修改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 打开一个 Pull Request
📄 许可证
MIT © 2024
🔗 相关链接
如果这个项目对你有帮助,请考虑给一个 ⭐️
