【问题标题】:Vue computed property updated, but component did not re-renderVue 计算属性已更新,但组件未重新渲染
【发布时间】: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}] 传递给&lt;v-data-table :items="dataToDisplay" :item-key="idNumber"&gt;
  • 这很好用,但有时数据表组件不更新。你什么时候有这种行为?请分享商店代码
  • 存储相当复杂,但本质上流程是:用户删除或过滤掉一个表格元素。这会向 firebase 提交请求,并同时从商店中删除该元素。

标签: javascript vue.js vuetify.js


【解决方案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 (抱歉问题含糊不清,我更新了模板)。在您的解决方案中,用户操作后更新项目的逻辑在哪里?那么它们会在方法内部,而不是通过计算字段触发吗?
猜你喜欢
  • 2021-05-10
  • 2020-07-18
  • 2021-10-04
  • 2019-10-03
  • 2018-12-04
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
  • 2017-11-09
相关资源
最近更新 更多