vue-fantable
Version:
Vue table component for huge data
355 lines (314 loc) • 12.2 kB
Markdown
> 遇到任何组件和文档有关问题,请提交 [issue](https://github.com/fall-zhang/vue-fantable/issues)
>
> 如果我看的更远,那是因为我站在巨人的肩膀上。
# vue-fantable
[](http://www.opensource.org/licenses/mit-license.php)
[English](./README-EN.md) | **中文**
## 介绍
如果你的项目使用 vue2,建议使用 [vue-easytable](https://www.npmjs.com/package/vue-easytable)
本项目由 vue-easytable 更新而来,支持 Vue3,使用 ESM(建议 node V18+)体积更小,像使用 vue-easytable 一样,使用 vue-fantable 吧。
> 作者维护该应用,作为低代码平台的依赖,而当前工作重心并不在该项目。仅当有有重大问题时,我会修复这些问题。
## 特点
- 采用虚拟滚动技术,支持 30 万行数据展示和实时编辑
- 永久开源免费。当然你也可以选择捐赠,保证项目长期维护和功能加速开发
## API & 文档
> 组件使用方式和 vue-easytable 尽可能保持一致。
- [vue-fantable 文档](https://fall-zhang.github.io/vue-fantable/#/zh/doc/intro)
- [CHANGE_LOG](./CHANGE-LOG.md)
## 安装
确保 Vue 版本至少为 3.2
```
npm install vue-fantable
# or
yarn add vue-fantable
```
## 使用
讲一下内容添加到 main.js:
```javascript
import { createApp } from "vue";
import "vue-fantable/libs/theme-default.css";
import App from './app.vue'
import VueFantable from "vue-fantable";
const app = createApp(App)
app.use(VueFantable);
app.mounted('#app')
```
### 示例 1
```vue
<template>
<fan-table :columns="columns" :table-data="tableData" :max-height="400"/>
</template>
<script >
export default {
data() {
return {
columns: [
{ field: "name", key: "a", title: "Name", align: "center" },
{ field: "date", key: "b", title: "Date", align: "left" },
{ field: "hobby", key: "c", title: "Hobby", align: "right" },
{ field: "address", key: "d", title: "Address" },
],
tableData: [
{
name: "John",
date: "1900-05-20",
hobby: "coding and coding repeat",
address: "No.1 Century Avenue, Shanghai",
},
{
name: "Dickerson",
date: "1910-06-20",
hobby: "coding and coding repeat",
address: "No.1 Century Avenue, Beijing",
},
{
name: "Larsen",
date: "2000-07-20",
hobby: "coding and coding repeat",
address: "No.1 Century Avenue, Chongqing",
},
{
name: "Geneva",
date: "2010-08-20",
hobby: "coding and coding repeat",
address: "No.1 Century Avenue, Xiamen",
},
{
name: "Jami",
date: "2020-09-20",
hobby: "coding and coding repeat",
address: "No.1 Century Avenue, Shenzhen",
},
],
};
},
};
</script>
```
### 示例 2
```vue
<template>
<div class="spreadsheet">
<fan-table style="word-break: break-word" fixed-header :scroll-width="0" :max-height="500" border-y :columns="columns"
:table-data="tableData" row-key-field-name="rowKey" :virtual-scroll-option="virtualScrollOption"
:cell-autofill-option="cellAutofillOption" :edit-option="editOption"
:contextmenu-body-option="contextmenuBodyOption" :contextmenu-header-option="contextmenuHeaderOption"
:row-style-option="rowStyleOption" :column-width-resize-option="columnWidthResizeOption" />
</div>
</template>
<script lang="jsx">
const COLUMN_KEYS = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N']
export default {
name: 'SpreadSheet',
data() {
return {
// start row index
startRowIndex: 0,
columnWidthResizeOption: {
enable: true,
},
virtualScrollOption: {
// 是否开启
enable: true,
scrolling: this.scrolling,
},
cellAutofillOption: {
directionX: true,
directionY: true,
beforeAutofill: ({
direction,
sourceSelectionRangeIndexes,
targetSelectionRangeIndexes,
sourceSelectionData,
targetSelectionData,
}) => { },
afterAutofill: ({
direction,
sourceSelectionRangeIndexes,
targetSelectionRangeIndexes,
sourceSelectionData,
targetSelectionData,
}) => { },
},
// edit option 可控单元格编辑
editOption: {
beforeCellValueChange: ({ row, column, changeValue }) => { },
afterCellValueChange: ({ row, column, changeValue }) => { },
},
// contextmenu header
contextmenuHeaderOption: {
// before contextmenu show. 你可以在这里更改 contextmenu 配置
beforeShow: ({
isWholeColSelection,
selectionRangeKeys,
selectionRangeIndexes,
}) => {
// do something
},
afterMenuClick: ({
type,
selectionRangeKeys,
selectionRangeIndexes,
}) => {
// do something
},
contextmenus: [
{ type: 'CUT', },
{ type: 'COPY', },
{ type: 'SEPARATOR', },
{ type: 'EMPTY_COLUMN', },
{ type: 'SEPARATOR', },
{ type: 'LEFT_FIXED_COLUMN_TO', },
{ type: 'CANCEL_LEFT_FIXED_COLUMN_TO', },
{ type: 'RIGHT_FIXED_COLUMN_TO', },
{ type: 'CANCEL_RIGHT_FIXED_COLUMN_TO', },
],
},
contextmenuBodyOption: {
// before contextmenu show. 你可以在这里更改 contextmenu 配置
beforeShow: ({
isWholeRowSelection,
selectionRangeKeys,
selectionRangeIndexes,
}) => {
console.log('---contextmenu body beforeShow--')
console.log('isWholeRowSelection::', isWholeRowSelection)
console.log('selectionRangeKeys::', selectionRangeKeys)
console.log(
'selectionRangeIndexes::',
selectionRangeIndexes,
)
},
afterMenuClick: ({
type,
selectionRangeKeys,
selectionRangeIndexes,
}) => {
console.log('---contextmenu body afterMenuClick--')
console.log('type::', type)
console.log('selectionRangeKeys::', selectionRangeKeys)
console.log('selectionRangeIndexes::', selectionRangeIndexes)
},
contextmenus: [
{ type: 'CUT', },
{ type: 'COPY', },
{ type: 'SEPARATOR', },
{ type: 'INSERT_ROW_ABOVE', },
{ type: 'INSERT_ROW_BELOW', },
{ type: 'SEPARATOR', },
{ type: 'REMOVE_ROW', },
{ type: 'EMPTY_ROW', },
{ type: 'EMPTY_CELL', },
],
},
rowStyleOption: {
clickHighlight: false,
hoverHighlight: false,
},
tableData: [],
}
},
computed: {
// current local
columns() {
let columns = [
{
field: 'index',
key: 'index',
// is operation column
operationColumn: true,
title: '',
width: 55,
fixed: 'left',
renderBodyCell: this.renderRowIndex,
},
]
columns = columns.concat(
COLUMN_KEYS.map((keyValue) => {
return {
title: keyValue,
field: keyValue,
key: keyValue,
width: 90,
edit: true,
}
}),
)
return columns
},
},
created() {
this.initTableData()
},
methods: {
// 渲染 row index
renderRowIndex({ row, column, rowIndex }) {
return (<span>{rowIndex + this.startRowIndex + 1}</span>)
},
scrolling({
startRowIndex,
visibleStartIndex,
visibleEndIndex,
visibleAboveCount,
visibleBelowCount,
}) {
this.startRowIndex = startRowIndex
},
initTableData() {
const tableData = []
for (let i = 0; i < 5000; i++) {
const dataItem = {
rowKey: i,
}
COLUMN_KEYS.forEach((keyValue) => {
dataItem[keyValue] = ''
})
if (i === 1 || i === 3) {
dataItem.C = 'YOU'
dataItem.D = 'CAN'
dataItem.E = 'TRY'
dataItem.F = 'ENTER'
dataItem.G = 'SOME'
dataItem.H = 'WORDS'
dataItem.I = '!!!'
}
tableData.push(dataItem)
}
this.tableData = tableData
},
},
}
</script>
<style lang="less">
.spreadsheet {
padding: 0 100px;
margin: 30px 0;
}
</style>
```
## 更多功能支持
**其它基础组件**
- [Loading 组件加载状态](https://fall-zhang.github.io/vue-fantable/#/zh/doc/base/loading)
- [Pagination 分页组件](https://fall-zhang.github.io/vue-fantable/#/zh/doc/base/pagination)
- [Contextmenu 右键菜单组件](https://fall-zhang.github.io/vue-fantable/#/zh/doc/base/contextmenu)
- [Icon 图标组件](https://fall-zhang.github.io/vue-fantable/#/zh/doc/base/icon)
- [Locale 国际化组件](https://fall-zhang.github.io/vue-fantable/#/zh/doc/base/locale)
**Table 组件**
- [国际化](https://fall-zhang.github.io/vue-fantable/#/zh/doc/locale)
- [主题定制 & 内置主题](https://fall-zhang.github.io/vue-fantable/#/zh/doc/theme)
- [虚拟滚动](https://fall-zhang.github.io/vue-fantable/#/zh/doc/table/virtual-scroll)
- [自定义事件](https://fall-zhang.github.io/vue-fantable/#/zh/doc/table/event-custom)
- [更多用法](https://fall-zhang.github.io/vue-fantable/#/zh/doc/table/usage)
如果没有你想要的的功能,请告诉[我](https://github.com/fall-zhang/vue-fantable/issues)
## 支持环境
- 所有现代浏览器
| <img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="Edge" width="24px" height="24px" /></br>Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/opera/opera_48x48.png" alt="Opera" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Opera |
| ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| Edge | last 2 versions | last 2 versions | last 2 versions | last 2 versions |
## 贡献者们
感谢 [easytable](https://github.com/Happy-Coding-Clans/vue-easytable) 原项目工作者们,以及维护者 [huangshuwei](https://github.com/Happy-Coding-Clans) 🙏,本项目继承自 vue-easytable@2.27.1。
### 如何贡献
- 点击 :star: 让更多的人了解到我们
- 如果你希望参与贡献,欢迎 Pull Request
## License
http://www.opensource.org/licenses/mit-license.php