Vue 列表项不会在状态更改时重新渲染
Posted
技术标签:
【中文标题】Vue 列表项不会在状态更改时重新渲染【英文标题】:Vue list items not re-rendered on state change 【发布时间】:2017-08-26 07:43:26 【问题描述】:我有一些对象数组,当用户单击按钮时,我会获取新数组并显示一些结果。
在我获取第二个数组之前它工作正常。当我用一个元素获取第一个数组,然后用两个元素获取数组时,它只会更改(添加或删除)第二个元素。
如何更改数组值:
fetchAsync(result)
this.issue = result.body;
issues
长什么样?
const issues = [
"id":100,
"key":"DEMO-123",
"summary":"Demo issue description",
"devices":[
"id":100,
"name":"iPhone6S",
"browsers":[
"id":100,
"name":"Safari",
"displayVariants":[
"id":100,
"issueKey":"DEMO-123",
"state":1,
"browserName":"safari",
"user":"user-1",
"landScope":false
]
]
]
]
而改变的值是issues[].devices[].browsers[].displayVariants[].state
出现嵌套变化时如何强制Vue重新渲染这个组件?
[编辑]
我呈现这样的问题:
<tr v-for="issue in issues">
<td>
<div> issue.key </div>
<div class="issue-description">[ issue.summary ]</div>
</td>
<template v-for="d in issue.devices">
<td v-for="browser in d.browsers">
<!-- d -->
<device v-for="variant in browser.displayVariants"
:variant="variant"
:browserId="browser.id"
:issueKey="issue.key"
:issueId="issue.id"
:deviceId="d.id"></device>
</td>
</template>
</tr>
和device
模板
<template>
<svg viewBox="0 0 30 30" class="mobileSVG" @click="changeState" :class="[state, landscape: variant.landScope]">
<use xlink:href="#mobile"/>
</svg>
</template>
【问题讨论】:
我认为问题在于您的渲染方法,请您粘贴一下吗?您是否为每个动态条目使用密钥? @aks 我添加了渲染issues
的模板
【参考方案1】:
我认为将密钥添加到您的列表中可以解决问题:
https://vuejs.org/v2/guide/list.html#key
Vue 尝试对 DOM 进行最小的更改,并认为第一项没有更改,因此不会重新渲染。在您的情况下,您已经拥有id
,使用它作为密钥应该可以解决问题。
【讨论】:
我使用的是 idx 密钥而不是我的 item.id 密钥,并且遇到了项目内容错误的奇怪问题。你救了我的命!【参考方案2】:Vue 无法检测到对数组所做的以下更改。 这是documentation。
当您直接使用索引设置项目时,例如 vm.items[indexOfItem] = newValue 当您修改数组的长度时,例如vm.items.length = newLength
vm
指的是组件实例。
要克服限制,请执行以下操作:
Vue.set(items, indexOfItem, newValue)
对于限制 2:
items.splice(newLength)
所以你可以这样做
this.$set(this.issues[0].devices[whateverIndex].browsers[anyIndex].displayVariants, indexOfVariant, valueOfVariant)
【讨论】:
以上是关于Vue 列表项不会在状态更改时重新渲染的主要内容,如果未能解决你的问题,请参考以下文章
Vuex 全局状态更改不会触发 Nuxt 中 v-for 循环中的重新渲染组件
在我滚动之前,react-virtualized 列表项不会使用更改的道具重新渲染