Vue 计算属性已更新,但组件未重新渲染
Posted
技术标签:
【中文标题】Vue 计算属性已更新,但组件未重新渲染【英文标题】:Vue computed property updated, but component did not re-render 【发布时间】:2020-12-16 02:46:57 【问题描述】:我正在用异步加载到 vuex 存储中的数据填充 vuetify 数据表。
用户输入可以更改存储,在这种情况下,我 dispatch
一个动作,异步拉取一些数据,commits
更改。
为了在数据加载时处理组件状态,我在商店中使用了loading
标志。加载数据时,设置为loading
,这样数据表就会呈现为空
...
computed:
... // a fairly long list of interdependent computed properties
loading()
return store.state.loading
,
dataToDisplay()
if(this.loading)
return []
else
return store.state.data
这很好用,但有时数据表组件不会更新,即使提供它的计算属性已更新(参见 vue 开发工具的屏幕截图)。
关于为什么计算属性不更新有几个答案(here、here)。但是有什么可以解释计算的属性确实更新正确,但组件没有重新渲染?如何解决?
有人提到here 使用:key
我试过了,但表格内容仍然没有更新。
[编辑] 提供数据表代码
<v-data-table
:key="loading"
:headers="headers"
:items="dataToDisplay"
:item-key="itemId"
disable-pagination hide-default-footer
>
<template v-slot:item="row">
<tr>
<td class="text-xs-right"> row.item.currentCondition </td>
<td class="text-xs-right"> row.item.nextCondition </td>
<td class="mx-2">
<v-btn icon class="mx-0" @click="editItem(row.item)">
<v-icon color="teal">mdi-pencil</v-icon>
</v-btn>
<v-btn icon class="mx-0" @click="deleteItem(row.item)">
<v-icon color="pink">mdi-delete</v-icon>
</v-btn>
</td>
</tr>
</template>
</v-data-table>
【问题讨论】:
从这篇文章中,我可以强制重新渲染。话虽如此,我最好知道发生了什么以提出更好的解决方案michaelnthiessen.com/force-re-render 如果您的key
更新,您的组件将自动重新渲染。否则你需要强制重新渲染。
好的,那么数据表的键是什么?你说的是item-key吗?为了提供更多上下文,我将 [col1:value, col2:value, col1:value,col2:value] 传递给<v-data-table :items="dataToDisplay" :item-key="idNumber">
这很好用,但有时数据表组件不更新。你什么时候有这种行为?请分享商店代码
存储相当复杂,但本质上流程是:用户删除或过滤掉一个表格元素。这会向 firebase 提交请求,并同时从商店中删除该元素。
【参考方案1】:
您可以使用数据属性 items: null
由您的函数填充并使用 v-for: (item, i) in items
将它们加载到您的 v-data-table
中
<template>
<v-data-table
:headers="headers"
:items="items"
:loading="loading"
></v-data-table>
</template>
<script>
export default
data ()
return
headers: [
text: 'Name', align: 'start', value: 'name',
text: 'Description', value: 'desc' ,
],
items: null,
loading: true
,
created:
addData()
this.items = store.state.data
this.loading = store.state.loading
</script>
【讨论】:
太好了,谢谢!不过,用户确实会不时修改状态。这意味着在那之后需要重新加载状态。所以我猜 created() 钩子可以用于初始化,但不能用于初始化。 Vuetify 使数据表在v-for
中使用的项目发生变化时更新。你可以使用计算,但我强烈建议也使用数据属性。
我没有使用 v-for (抱歉问题含糊不清,我更新了模板)。在您的解决方案中,用户操作后更新项目的逻辑在哪里?那么它们会在方法内部,而不是通过计算字段触发吗?以上是关于Vue 计算属性已更新,但组件未重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
vue 计算属性未重新计算 / computed 未触发 / computed 原理&源码分析