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]
          }
        })

然后我修改代码之后,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)
上一篇下一篇

猜你喜欢

热点阅读