使用内置过滤器的Vue.js b-table子组件:工作正常但非常缓慢
我有一个vue页面Main.vue,它从单独的vue文件Table.vue呈现组件。当我将所有逻辑都烘焙到Main.vue中时,自由格式文本过滤器工作正常。但现在我输入的几乎每个字符都会延迟,所以我想我的实现可能有问题 我在下面发布的代码经过了简化,即删除了分页和计算内容,以显示我所坚持的内容 表3.vue: Main.vue:使用内置过滤器的Vue.js b-table子组件:工作正常但非常缓慢,vue.js,filtering,bootstrap-vue,Vue.js,Filtering,Bootstrap Vue,我有一个vue页面Main.vue,它从单独的vue文件Table.vue呈现组件。当我将所有逻辑都烘焙到Main.vue中时,自由格式文本过滤器工作正常。但现在我输入的几乎每个字符都会延迟,所以我想我的实现可能有问题 我在下面发布的代码经过了简化,即删除了分页和计算内容,以显示我所坚持的内容 表3.vue: Main.vue: <template> <div v-if="details !== null"> <custtable :detail
<template>
<div v-if="details !== null">
<custtable :details="filteredDetails"/>
<br/>
</div>
</template>
<script>
import { API } from '@/common/api.js'
import Table from '@/components/Table'
export default {
name: 'Main',
data: function() {
return {
details: [],
filteredDetails: []
}
},
components: {
'custtable': Table
}
}
</script>
所以我想知道过滤器部分是否应该在表中。vue:它应该在Main.vue中吗?理想情况下,应该在哪里定义过滤器变量
如前所述,功能是存在的,但它似乎非常缓慢。最初的API调用通常会返回大约150个JSON条目,因此数据量不会太大
到目前为止,我一直在引用
任何和所有的输入是感激的 如果您的表具有唯一的ID字段,即主键,请通过主键属性指定该字段键名称。这将优化Vue重新呈现表的方式 i、 e.如果您的items数组有一个字段id,该id保证在所有数据行中都是唯一的,则设置prop primary=key=id 过滤还需要将每一行的数据序列化为包含所有行值的单个字符串,因此如果有许多字段或深嵌套字段,则可能需要一些时间 另一个选项是消除过滤器输入的干扰。与其将过滤器输入的v模型直接传递给b-table的过滤器属性,不如将其存储在一个中间变量中,并且只在如此多毫秒的无按键输入事件后更新发送给b-table的输入值的副本
在您的情况下,筛选器进程会在输入的每个字符的整个表中运行,这会重新触发Vue以重新呈现整个表。结合使用主键和输入去抖动应该可以提高性能 感谢特洛伊提供的信息丰富的回答。我确实设置了主键,这对渲染略有帮助,但仍然非常缓慢。看看下面的Vue检查器,它不应该列出实际的PK值而不是票证号吗?请参见此处:主键属性需要字段名,而不是字段值。它使用该名称从items行中查找值,并根据查找到的值为该行指定Vue:键。因此,每个都会分配一个唯一的Vue:key,因此如果行数据没有更改,Vue可以优化其渲染。它还可以重新排列DOM元素,即在排序或过滤已经呈现的元素时,只要vNode键没有改变。啊,这很有帮助!当我现在只使用常规的Inspect元素功能时,我可以看到每个元素都有一个带有票证号的数据pk属性。令人惊叹的如果您检查VM中的TR元素及其vNode引用,您还将看到根据行主键值分配了唯一的Vue键。只是想签入并查看用于在表单输入上取消公告的PR,它的工作方式很有魅力。谢谢你所做的一切!
<script>
export default {
name: 'Table',
props: ['details'],
data: function() {
return {
fields: [
{ key: 'ticket_number', sortable: true },
{ key: 'parent_id', label: 'Parent Ticket', sortable: true },
{ key: 'start', sortable: true, label: 'Start Date', formatter: (value) => { return moment(value, 'X').format('MM/DD/YYYY hh:mm:ss A') }},
],
// free text filter
filter: null
}
},
computed: {
rows: function(){
return this.details.length
}
},
created: function () {
this.filteredDetails = this.details
},
methods: {
onFiltered(filteredItems) {
// Trigger pagination to update the number of buttons/pages due to filtering
this.totalRows = filteredItems.length
this.currentPage = 1
}
}
}
<template>
<div v-if="details !== null">
<custtable :details="filteredDetails"/>
<br/>
</div>
</template>
<script>
import { API } from '@/common/api.js'
import Table from '@/components/Table'
export default {
name: 'Main',
data: function() {
return {
details: [],
filteredDetails: []
}
},
components: {
'custtable': Table
}
}
</script>