[英]VueJS, Vuetify, data-table - expandable, performance problem
我的 VueJS 和 Vuetify 項目有問題。 我想創建一個帶有可擴展行的表。 這將是一張訂單表,可以查看每個訂單的購買產品。 對於一頁,它應該顯示至少 100 行訂單。 為此,我使用了 Vuetify 框架<v-data-table>
。
在准備好一切之后,我意識到它可以工作,但是對於每一行的擴展,我必須等待幾秒鍾(它太長了 - 它必須是一個快速的系統)。 並且為了擴展所有可見記錄,需要等待超過20 秒的整頁延遲。
我從標准的 Vuetify <v-data-table>
開始,帶有一個show-expand
道具和一個 expand expanded-item
插槽 - 這是我的第一次嘗試 - 最慢。 其次,我嘗試自己創建 - 但使用 Vuetify:
<v-data-table>
<template v-slot:item="{item}">
<td @click="item.expanded = !item.expanded">expand / hide</td>
<!--- [my table content here - too long to post it here] -->
<tr v-if="item.expanded">
<td :colspan="headers.length">
<v-data-table>
<!--- [content of the nested table - also too long to post it here] -->
</v-data-table>
</tr>
</template>
</v-data-table>
有趣的是 - 我意識到v-if
比v-show
工作得更快,這是一個奇怪的事實,因為我認為將display: none
更改為 none 應該比將整個對象添加/刪除到 DOM 問題更小。
這種方法比第一種方法快一點,但還是太慢了。
我找到了一個提示,為我的表中的每個v-btn
設置:ripple="false"
並且我做到了 - 有所幫助,但只有一點點。 一切都在 Chrome 和 Firefox、Windows 和 Linux Fedora 和兩部 ZC31B32364CE19CA8ZFCD1 智能手機的三台設備上進行了測試。
我還應該怎么做?
先感謝您!
這篇優秀的文章表明 DOM 節點的原始數量對性能的影響最大。 也就是說,在我構建的示例應用程序中,我沒有遇到任何真正的性能瓶頸,以了解有關您的問題的更多信息。 包含表格的整個頁面在大約 1.25 秒內加載(來自本地主機),無論它是處於開發模式還是生產版本。 JavaScript控制台計時器報告說,同時擴展或收縮所有 100 行平均只需要大約 0.3 秒。 最重要的是,我認為您可以實現您正在尋找的優化,而不必放棄 Vuetify 的便利。
v-data-table
內的v-data-table
嗎?這就是我所做的。 我創建了一個簡單的 Vue/Vuetify 應用程序,其中包含一個具有 100 個可擴展行的VDataTable
。 (數據來自隨機用戶 API )。 我使用這種方法來計算 DOM 節點。 以下是一些參數/信息:
VSimpleTable
vue create myapp
和vue add vuetify
的VDataTable
實際上會從 DOM 中添加/刪除擴展行以下是結果的一些近似統計數據(這些數字在不同條件下略有波動——YMMV):
這是我的應用的App.vue
頁面的代碼。 v-data-table
幾乎是頁面上唯一的組件(除了切換按鈕),我沒有導入任何外部組件。
<template>
<v-app>
<v-btn
color="primary"
@click="toggleExpansion"
>
Toggle Expand All
</v-btn>
<v-data-table
:expanded.sync="expanded"
:headers="headers"
:items="items"
item-key="login.uuid"
:items-per-page="100"
show-expand
>
<template #item.name="{ value: name }">
{{ name.first }} {{ name.last }}
</template>
<template #expanded-item="{ headers, item: person }">
<td :colspan="headers.length">
<v-card
class="ma-2"
max-width="500px"
>
<v-row>
<v-col cols="4">
<v-img
:aspect-ratio="1"
contain
:src="person.picture.thumbnail"
/>
</v-col>
<v-col cols="8">
<v-simple-table>
<template #default>
<tbody>
<tr>
<th>Name</th>
<td class="text-capitalize">
{{ person.name.title }}. {{ person.name.first }} {{ person.name.last }}
</td>
</tr>
<tr>
<th>Address</th>
<td class="text-capitalize">
{{ person.location.street.number }} {{ person.location.street.name }}<br>
{{ person.location.city }}, {{ person.location.state }} {{ person.location.postcode }}
</td>
</tr>
<tr>
<th>DOB</th>
<td>
{{ (new Date(person.dob.date)).toLocaleDateString() }} (age {{ person.dob.age }})
</td>
</tr>
</tbody>
</template>
</v-simple-table>
</v-col>
</v-row>
</v-card>
</td>
</template>
</v-data-table>
</v-app>
</template>
<script>
import axios from 'axios'
export default {
name: 'App',
data: () => ({
expanded: [],
headers: [
{ text: 'Name', value: 'name' },
{ text: 'Gender', value: 'gender' },
{ text: 'Phone', value: 'phone' },
{ text: 'Cell', value: 'cell' },
{ text: 'Country', value: 'nat' },
{ text: '', value: 'data-table-expand' },
],
items: [],
}),
created () {
axios.get('https://randomuser.me/api/?seed=stackoverflow&results=100')
.then(response => {
this.items = response.data.results
})
},
methods: {
toggleExpansion () {
console.time('expansion toggle')
this.expanded = this.expanded.length ? [] : this.items
console.timeEnd('expansion toggle')
},
},
}
</script>
你可以在這個 codeply 中看到一個工作演示。 希望這可以幫助!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.