v-for无法在获取数据后更新dom
2019-12-31 本文已影响0人
E1FANG
在axios获取数据后,数据成功修改,但是dom依然没有刷新,代码如下:
<el-select v-model="value" value-key="id" placeholder="请选择" size="samll">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
...
data() {
return {
options: [],
opReady: false
}
},
getStore(checkPhrases) {
getMysql133(checkPhrases).then(res => {
const result = res.data.rows
result.forEach((e, i) => {
this.options[i] = {
value: e[0],
label: e[1]
}
})
this.options = newArr
this.opReady = true
})
}
选择列表仍未空,显示no-data
之后在el-select上绑定v-if='opReady'
后 dom成功更新,但是意识到这不是长久的办法,因为后续要根据选中的数据进行数据操作,所以继续深究
找到原理
官方文档
官方文档上有说明这个问题
由于JavaScript的限制,Vue不能检测以下变动的数组:
- 当你通过索引直接设置一个数组项时,例如上面代码中的
result.forEach((e, i) => {
this.options[i] = {
value: e[0],
label: e[1]
}
})
- 当你修改数组长度时 例如:
vm.items.length = newLength
然后我修改代码之后,dom就实时更新了
getMysql133(checkPhrases).then(res => {
const result = res.data.rows
var newArr = []
result.forEach((e, i) => {
newArr[i] = {
value: e[0],
label: e[1]
}
})
this.options = newArr
this.opReady = true
})
用一个新数组去存储,然后再复制给回options,这样就可以避免通过索引设置数组项。
当然官方文档时推荐通过vm.$set
来修改的
以下是官方文档原文
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将在响应式系统内触发状态更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,你可以使用 splice
:
vm.items.splice(newLength)