Vuejs 和 Vue.set(),更新数组

问题描述 投票:0回答:5

我是 Vuejs 新手。做了一些东西,但我不知道这是简单/正确的方法。

我想要什么

我想要数组中的一些日期并在事件中更新它们。首先我尝试了 Vue.set,但没有成功。现在更改我的数组项后:

this.items[index] = val;
this.items.push();

我向数组中推送()任何内容,它都会更新..但有时最后一个项目会被隐藏,不知何故...我认为这个解决方案有点hacky,我怎样才能使它稳定?

简单代码在这里:

new Vue({
  el: '#app',
  data: {
  	f: 'DD-MM-YYYY',
    items: [
      "10-03-2017",
      "12-03-2017"
    ]
  },
  methods: {
    
    cha: function(index, item, what, count) {
    	console.log(item + " index > " + index);
      val = moment(this.items[index], this.f).add(count, what).format(this.f);
  		this.items[index] = val;
      this.items.push();
      console.log("arr length:  " + this.items.length);
    }
  }
})
ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(index, item) in items">
    <br><br>
      <button v-on:click="cha(index, item, 'day', -1)">
      - day</button>
      {{ item }}
      <button v-on:click="cha(index, item, 'day', 1)">
      + day</button>
    <br><br>
    </li>
  </ul>
</div>

javascript vue.js momentjs vuejs2
5个回答
133
投票

编辑2

  • 对于需要反应性的all对象更改,请使用
    Vue.set(object, prop, value)
  • 对于数组突变,您可以查看当前支持的列表这里

编辑1

对于 vuex 你会想做

Vue.set(state.object, key, value)


原创

对于其他提出这个问题的人来说。它出现在 Vue 2 中的某个时刻。*他们删除了

this.items.$set(index, val)
,转而使用
this.$set(this.items, index, val)

Splice 仍然可用,这里是 vue 中可用的数组突变方法的链接link


62
投票

如果您像这样操作数组,VueJS 无法获取您对状态的更改。

正如常见初学者陷阱中所解释的,您应该使用数组方法,如push、splice或其他方法,并且永远不要像这样修改索引

a[2] = 2
或数组的.length属性。

new Vue({
  el: '#app',
  data: {
    f: 'DD-MM-YYYY',
    items: [
      "10-03-2017",
      "12-03-2017"
    ]
  },
  methods: {

    cha: function(index, item, what, count) {
      console.log(item + " index > " + index);
      val = moment(this.items[index], this.f).add(count, what).format(this.f);

      this.items.$set(index, val)
      console.log("arr length:  " + this.items.length);
    }
  }
})
ul {
  list-style-type: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.11/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"></script>
<div id="app">
  <ul>
    <li v-for="(index, item) in items">
      <br><br>
      <button v-on:click="cha(index, item, 'day', -1)">
      - day</button> {{ item }}
      <button v-on:click="cha(index, item, 'day', 1)">
      + day</button>
      <br><br>
    </li>
  </ul>
</div>


22
投票

如前所述 - VueJS 根本无法跟踪这些操作(数组元素分配)。 VueJS 使用数组跟踪的所有操作都在here。 但我会再次复制它们:

  • 推()
  • 弹出()
  • 移位()
  • 取消移位()
  • 拼接()
  • 排序()
  • 反转()

在开发过程中,您面临一个问题 - 如何忍受这个问题:)。

push()、pop()、shift()、unshift()、sort()和reverse()非常简单,在某些情况下可以帮助你,但主要焦点在于splice(),它可以让你有效地修改 VueJs 将跟踪的数组。 所以我可以分享一些最常用的数组方法。

您需要替换数组中的项目:

// note - findIndex might be replaced with some(), filter(), forEach() 
// or any other function/approach if you need 
// additional browser support, or you might use a polyfill
const index = this.values.findIndex(item => {
          return (replacementItem.id === item.id)
        })
this.values.splice(index, 1, replacementItem)

注意:如果您只需要修改项目字段 - 您可以通过以下方式完成:

this.values[index].itemField = newItemFieldValue

这将由 VueJS 跟踪,因为项目(对象)字段将被跟踪。

您需要清空数组:

this.values.splice(0, this.values.length)

实际上你可以用这个函数做更多splice() - w3schools链接 您可以添加多条记录、删除多条记录等

Vue.set() 和 Vue.delete()

Vue.set() 和 Vue.delete() 可用于将字段添加到 UI 版本的数据中。例如,您的对象中需要一些额外的计算数据或标志。您可以为您的对象或对象列表(在循环中)执行此操作:

 Vue.set(plan, 'editEnabled', true) //(or this.$set)

并在 Axios 调用之前以相同的格式将编辑后的数据发送回后端:

 Vue.delete(plan, 'editEnabled') //(or this.$delete)

0
投票

另一种解决问题的更轻量级的方法可能是,暂时编辑数组,然后将整个数组分配回您的变量。因为 Vue 不会监视单个项目,它会监视正在更新的整个变量。

所以你这也应该有效:

var tempArray[];

tempArray = this.items;

tempArray[targetPosition]  = value;

this.items = tempArray;

这也应该更新你的 DOM。


0
投票

我来到这里是因为我在使用 vue 时遇到了很多次问题,所以将其留在这里以供将来参考:

这是错误的/没有反应:

this.items = resp.items; // got from api
for(let i = 0; i < this.items.length; i++){
  // if you add a new property here, it's not responsive later
  this.items[i].selected = false;
}

这是正确的/有反应的:

const items = resp.items; // got from api
for(let i = 0; i < items.length; i++){
  // add a new property here
  items[i].selected = false;
}
// getters and setters are created for all properties
this.items = items;
© www.soinside.com 2019 - 2024. All rights reserved.