提交 a94d7059 编写于 作者: View Design's avatar View Design

Mon Mar 18 15:22:00 CST 2024 inscode

上级 61702be5
<template> <template>
<div> <div id="app">
<i-table :data="tableData" :columns="tableColumns" :rowHeight="30" :visibleRowCount="10" /> <VirtualScrollTable :data="data" :columns="columns" :height="height"></VirtualScrollTable>
</div> </div>
</template> </template>
<script> <script>
import iTable from "./components/table.vue"; import VirtualScrollTable from './components/table.vue';
export default { export default {
components: { components: { VirtualScrollTable },
iTable, data: {
}, data: [],
data() { columns: [
return { {
tableData: [ name: 'id',
{ id: 1, name: "John Doe", age: 30 }, label: 'ID'
{ id: 2, name: "Jane Doe", age: 25 }, },
{ id: 3, name: "Bob Smith", age: 40 }, {
{ id: 4, name: "Alice Johnson", age: 35 }, name: 'name',
{ id: 5, name: "Tom Brown", age: 28 }, label: '姓名'
{ id: 6, name: "Sara Lee", age: 32 }, },
{ id: 7, name: "Mike Smith", age: 45 }, {
{ id: 8, name: "Lucy Chen", age: 27 }, name: 'age',
{ id: 9, name: "David Wang", age: 38 }, label: '年龄'
{ id: 10, name: "Grace Zhang", age: 31 }, }
{ id: 11, name: "Jack Ma", age: 50 }, ],
{ id: 12, name: "Maggie Lee", age: 29 }, height: 300
{ id: 1, name: "John Doe", age: 30 },
{ id: 2, name: "Jane Doe", age: 25 },
{ id: 3, name: "Bob Smith", age: 40 },
{ id: 4, name: "Alice Johnson", age: 35 },
{ id: 5, name: "Tom Brown", age: 28 },
{ id: 6, name: "Sara Lee", age: 32 },
{ id: 7, name: "Mike Smith", age: 45 },
{ id: 8, name: "Lucy Chen", age: 27 },
{ id: 9, name: "David Wang", age: 38 },
{ id: 10, name: "Grace Zhang", age: 31 },
{ id: 11, name: "Jack Ma", age: 50 },
{ id: 12, name: "Maggie Lee", age: 29 },
{ id: 1, name: "John Doe", age: 30 },
{ id: 2, name: "Jane Doe", age: 25 },
{ id: 3, name: "Bob Smith", age: 40 },
{ id: 4, name: "Alice Johnson", age: 35 },
{ id: 5, name: "Tom Brown", age: 28 },
{ id: 6, name: "Sara Lee", age: 32 },
{ id: 7, name: "Mike Smith", age: 45 },
{ id: 8, name: "Lucy Chen", age: 27 },
{ id: 9, name: "David Wang", age: 38 },
{ id: 10, name: "Grace Zhang", age: 31 },
{ id: 11, name: "Jack Ma", age: 50 },
{ id: 12, name: "Maggie Lee", age: 29 },
{ id: 1, name: "John Doe", age: 30 },
{ id: 2, name: "Jane Doe", age: 25 },
{ id: 3, name: "Bob Smith", age: 40 },
{ id: 4, name: "Alice Johnson", age: 35 },
{ id: 5, name: "Tom Brown", age: 28 },
{ id: 6, name: "Sara Lee", age: 32 },
{ id: 7, name: "Mike Smith", age: 45 },
{ id: 8, name: "Lucy Chen", age: 27 },
{ id: 9, name: "David Wang", age: 38 },
{ id: 10, name: "Grace Zhang", age: 31 },
{ id: 11, name: "Jack Ma", age: 50 },
{ id: 12, name: "Maggie Lee", age: 29 },
{ id: 1, name: "John Doe", age: 30 },
{ id: 2, name: "Jane Doe", age: 25 },
{ id: 3, name: "Bob Smith", age: 40 },
{ id: 4, name: "Alice Johnson", age: 35 },
{ id: 5, name: "Tom Brown", age: 28 },
{ id: 6, name: "Sara Lee", age: 32 },
{ id: 7, name: "Mike Smith", age: 45 },
{ id: 8, name: "Lucy Chen", age: 27 },
{ id: 9, name: "David Wang", age: 38 },
{ id: 10, name: "Grace Zhang", age: 31 },
{ id: 11, name: "Jack Ma", age: 50 },
{ id: 12, name: "Maggie Lee", age: 29 },
{ id: 1, name: "John Doe", age: 30 },
{ id: 2, name: "Jane Doe", age: 25 },
{ id: 3, name: "Bob Smith", age: 40 },
{ id: 4, name: "Alice Johnson", age: 35 },
{ id: 5, name: "Tom Brown", age: 28 },
{ id: 6, name: "Sara Lee", age: 32 },
{ id: 7, name: "Mike Smith", age: 45 },
{ id: 8, name: "Lucy Chen", age: 27 },
{ id: 9, name: "David Wang", age: 38 },
{ id: 10, name: "Grace Zhang", age: 31 },
{ id: 11, name: "Jack Ma", age: 50 },
{ id: 12, name: "Maggie Lee", age: 29 },
{ id: 1, name: "John Doe", age: 30 },
{ id: 2, name: "Jane Doe", age: 25 },
{ id: 3, name: "Bob Smith", age: 40 },
{ id: 4, name: "Alice Johnson", age: 35 },
{ id: 5, name: "Tom Brown", age: 28 },
{ id: 6, name: "Sara Lee", age: 32 },
{ id: 7, name: "Mike Smith", age: 45 },
{ id: 8, name: "Lucy Chen", age: 27 },
{ id: 9, name: "David Wang", age: 38 },
{ id: 10, name: "Grace Zhang", age: 31 },
{ id: 11, name: "Jack Ma", age: 50 },
{ id: 12, name: "Maggie Lee", age: 29 },
],
tableColumns: ["ID", "Name", "Age"],
};
}, },
}; mounted() {
// 模拟生成大量数据
for (let i = 0; i < 10000; i++) {
this.data.push({
id: i + 1,
name: '姓名' + (i + 1),
age: Math.floor(Math.random() * 100)
})
}
}
}
</script> </script>
<template> <template>
<div class="vue-table" ref="tableWrapper" @scroll="handleScroll"> <div class="table-wrapper">
<table> <table :height="height" ref="table">
<thead> <thead>
<tr> <tr>
<th v-for="column in columns">{{ column }}</th> <th v-for="column in columns" :key="column.name">
{{ column.label }}
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-for="(row, index) in visibleRows" :key="index"> <tr v-for="item in renderedData" :key="item.id">
<td v-for="(value, key) in row">{{ value }}</td> <td v-for="column in columns" :key="column.name">
{{ item[column.name] }}
</td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
...@@ -17,71 +21,60 @@ ...@@ -17,71 +21,60 @@
<script> <script>
export default { export default {
name: 'VirtualScrollTable',
props: { props: {
data: { data: {
type: Array, type: Array,
required: true, required: true
}, },
columns: { columns: {
type: Array, type: Array,
required: true, required: true
}, },
rowHeight: { height: {
type: Number, type: Number,
required: true, default: 300
}, }
visibleRowCount: {
type: Number,
required: true,
},
}, },
data() { data () {
return { return {
renderedData: [],
scrollTop: 0, scrollTop: 0,
lastRenderedIndex: 0, visibleRowsCount: 0,
}; rowHeight: 50
}
}, },
computed: { watch: {
visibleRows() { scrollTop () {
const startIndex = Math.floor(this.scrollTop / this.rowHeight); this.updateRenderedData()
const endIndex = startIndex + this.visibleRowCount; }
this.lastRenderedIndex = endIndex;
return this.data.slice(startIndex, endIndex);
},
tableHeight() {
return this.rowHeight * this.data.length;
},
wrapperHeight() {
return this.rowHeight * this.visibleRowCount;
},
}, },
methods: { mounted () {
handleScroll(event) { this.visibleRowsCount = Math.ceil(this.height / this.rowHeight)
this.scrollTop = event.target.scrollTop; this.updateRenderedData()
},
}, },
}; methods: {
updateRenderedData () {
const startIndex = Math.floor(this.scrollTop / this.rowHeight)
const endIndex = startIndex + this.visibleRowsCount
this.renderedData = this.data.slice(startIndex, endIndex)
}
}
}
</script> </script>
<style> <style>
.vue-table { .table-wrapper {
height: 100%; overflow-y: auto;
overflow-y: scroll;
} }
table { table {
width: 100%;
border-collapse: collapse; border-collapse: collapse;
table-layout: fixed; width: 100%;
} }
th, th, td {
td { border: 1px solid #ddd;
padding: 8px; padding: 5px;
text-align: left;
border-bottom: 1px solid #ddd;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
} }
</style> </style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册