加载异步数据后,对Vue子组件中的数据表行执行操作



我有一个使用Vuetify v-datatable的子组件,当显示该组件及其父组件的页面显示时,我希望突出显示列表中的第一个项目(该项目的数据也显示在父组件中该项目的上方(。我还希望在行被选中时高亮显示,并且该行的数据显示在父行中。

基于这个答案,我让第二部分工作正常,第一部分(在初始显示中突出显示第一行(工作正常,但只是在一定程度上。

<template>
<div>
<v-data-table
:headers="headers"
:items="items"
:search="search"
:key="tableKey"
:pagination.sync="pagination"
disable-initial-sort
rowKey
>
<template slot="items" slot-scope="props">
<tr @click="clicked(props.item)" :class="{'secondary': props.item[rowKey]===selectedCode}">
<td v-for="header in headers" :key="header.value">
<BaseTableColumn
:item="props.item"
:index="header.value"
:format="header.format"
/>
</td>
</tr>
</template>
</v-data-table>
</div>
</template>
<script>
export default {
name: 'BaseTable',
props: {
headers: Array,
items: Array,
search: String,
tableKey: String,
rowKey: String,
},
data: () => ({
pagination: {
rowsPerPage: 10,
totalItems: -1,
},
selectedCode: -1,
itemsYN: false,
}),
components: {
BaseTableColumn: () => import('@/components/base/BaseTableColumn'),
},
methods: {
clicked(row) {
window.scrollTo(0, 0);
this.selectedCode = row[this.rowKey];
this.$set(row, 'selected', true);
this.$emit('rowClick', row);
},
},
mounted() {
// Select the first item in the list of items (if there are any)
// and highlight it.
if (this.items.length > 0) {
this.selectedCode = this.items[0][this.rowKey];
this.$set(this.items[0], 'selected', true);
}
},
};
</script>

其中该组件是从父级调用的,如:

<BaseTable
:headers="headers"
:items="alerts"
:search="search"
rowKey="messageId"
@rowClick="rowClick"
/>

到目前为止,我已经在mounted()钩子中获得了初始高亮显示的代码。当所有的items数据在装载时都已经可用时,这种方法可以很好地工作,但如果获取数据的调用需要更长的时间,并且直到它超过生命周期中的那个点才加载,那么我就不会得到突出显示。如果我使用created()挂钩也是如此

我的想法是观看items道具,一旦它被填充,就调用高亮显示代码,就像这样:

watch: {
items(val) {
if (this.items.length > 0) {
this.highlightFirst(val)
}
},
},
methods: {
clicked(row) {
window.scrollTo(0, 0);
this.selectedCode = row[this.rowKey];
this.$set(row, 'selected', true);
this.$emit('rowClick', row);
},
highlightFirst(items) {
this.selectedCode = this.items[0][this.rowKey];
this.$set(this.items[0], 'selected', true);
},
},
mounted() {
// Select the first item in the list of items (if there are any)
// and highlight it.
if (this.items.length > 0) {
this.highlightFirst(this.items);
}
},

但是,由于每当选择一行时都会更新items,这会覆盖clicked()方法,因此第一个项目会高亮显示,而不是单击的项目。

由于此组件是14个组件的子组件,因此我希望在此组件中处理此问题,而不是添加来自所有父组件的传入道具来指示何时加载数据。如何在初始页面加载时高亮显示第一行,等待异步数据传入,而不在单击单个行时踩clicked()方法?

您可以声明一个变量,当click按下按钮时可以在其中存储true,当输入watch时可以设置false

data: (){
return {
fromClick: true;
}
},
watch: {
items(val) {
if (!fromClick) {
this.highlightFirst();
}
this.fromClick = false;
}
},
methods: {
clicked(row) {
this.fromClick = true;
window.scrollTo(0, 0);
this.hightlightRow(row);
this.$emit('rowClick', row);
},
highlightFirst() {
if (this.items.length > 0) {
this.hightlightRow(this.items[0]);
}
},
hightlightRow(row) {
this.selectedCode = row[this.rowKey];
this.$set(row, 'selected', true);
}
},
mounted() {
// Select the first item in the list of items (if there are any)
// and highlight it.
this.highlightFirst();
},

我用下面的代码以更简单的方式解决了这个问题。

props: {
headers: Array,
items: Array,
search: String,
tableKey: String,
rowKey: String,
},
data: () => ({
...
selectedCode: -1,
}),  
methods: {
clicked(row) {
window.scrollTo(0, 0);
this.selectedCode = row[this.rowKey];
this.$set(row, 'selected', true);
this.$emit('rowClick', row);
},
highlightFirst(items) {
this.selectedCode = this.items[0][this.rowKey];
this.$set(this.items[0], 'selected', true);
},
},
updated() {
if (this.selectedCode === -1 && && (typeof this.items === 'object') && this.items.length > 0) {
this.highlightFirst(this.items);
}
},

一旦highlightFirst()运行后this.selectedCode有了值,update()中就不会发生任何事情,并且当单击一行时,clicked()方法可以正常工作。

最新更新