【问题标题】:Vuejs and Vue.set(), update arrayVuejs 和 Vue.set(),更新数组
【发布时间】:2017-08-06 01:57:17
【问题描述】:

我是 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


    【解决方案1】:

    编辑 2

    • 对于需要反应性的所有对象更改,请使用Vue.set(object, prop, value)
    • 数组突变可以看目前支持的列表here

    编辑 1

    对于 vuex,你会想做Vue.set(state.object, key, value)


    原创

    因此,仅针对提出此问题的其他人。它出现在 Vue 2 的某个时刻。* 他们删除了 this.items.$set(index, val) 以支持 this.$set(this.items, index, val)

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

    【讨论】:

    • 我需要提供什么字符串作为“索引”?
    • @Kokodoko 你能澄清你想要做什么吗?如果它是一个数组,它应该是索引的数字。如果您在对象上设置字段,则字符串将是。
    • 啊,好吧,我的 IDE 坚持它必须是一个字符串,一定是一个小故障。
    • Vue.set 不适用于 vuex。并且 this.$set 已弃用。
    • @MartinCalvert 它说“向对象添加属性时”。那是 Vue.set 的主要目的,与 vuex 无关。弃用,我在链接上阅读了它,但现在再次阅读,我并不完全理解它。 stackoverflow.com/questions/36671106/…
    【解决方案2】:

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

    正如Common Beginner Gotchas 中所解释的,您应该使用诸如 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>

    【讨论】:

    • 正如文档中所说,$set 只是一个漂亮的 .splice()。这是有道理的,因为就像他们在文档中所说的那样,您应该使用它的方法修改数组。
    • 请不要将制表符缩进与空格缩进结合起来,制表符的大小在 SE 应用程序上明显不同,难以阅读您的代码
    • 在我的情况下,用于推送操作的 ES6 扩展运算符不能与 vue 一起工作
    【解决方案3】:

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

    • 推()
    • pop()
    • shift()
    • unshift()
    • 拼接()
    • 排序()
    • 反向()

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

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

    需要替换数组中的Item:

    // 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 跟踪为 item(Object) 字段将被跟踪。

    你需要清空数组:

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

    其实你可以做更多这个功能splice() - w3schools link 可以添加多条记录,删除多条记录等。

    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)
    

    【讨论】:

      【解决方案4】:

      一种替代方法 - 并且更轻量级的方法来解决您的问题 - 可能只是临时编辑数组,然后将整个数组分配回您的变量。因为 Vue 不监视单个项目,它会监视整个变量的更新。

      所以你也应该这样工作:

      var tempArray[];
      
      tempArray = this.items;
      
      tempArray[targetPosition]  = value;
      
      this.items = tempArray;
      

      这也应该更新你的 DOM。

      【讨论】:

        【解决方案5】:

        在这里观察对象和数组的反应:

        https://vuejs.org/v2/guide/reactivity.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-26
          • 2017-11-10
          • 2018-04-10
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多