如何遍历数组并将属性添加到vue.js中的所有对象

时间:2019-06-18 16:21:21

标签: javascript vue.js

在Vue.js中,为了向虚拟DOM中已有的对象添加属性/数组项,you have to use the $set function

这是错误的方式:
对象: this.myObject.newProperty = "value";
数组: this.myArray[3] = object;

这是正确的方法:
对象: this.$set(this.myObject, "newProperty", "value");
数组: this.$set(this.myArray, 3, object);

我的问题是您如何设置数组中所有对象的属性?

这是错误的方式:

for (var i = 0; i < this.myArray.length; i++) {
    this.myArray[i].newProperty = "value";
}

那么,我使用$ set进行此操作的方法是什么?

4 个答案:

答案 0 :(得分:1)

您继续使用索引循环执行this.$set(this.myArray, 3, object);。 修改对象后,类似的东西。

var newObject = Object.assign({}, this.myArray[i], {newProperty: 'value'} ); // Immutable object created
this.$set(this.myArray, i, newObject);

这将是低效的,因为它将在每次迭代时调用$set。 因此您可以在数组上做一个映射,然后从内部返回一个新的Object。

const newArray = myArray.map(object => {
   return Object.assign({}, object, {newProperty: 'value'} );
   //or by ES6 spread operator
   return {...object, newProperty: 'value'};
});

然后将您的数组设置为重新渲染Vuejs。

希望,这将给出想法。尽管上下文可能会根据您的实现方式而有所不同!

答案 1 :(得分:1)

您的作品经过一些调整的代码:

new Vue({
  el: "#app",
  data: {
    todos: [{
        text: "Learn JavaScript",
        done: false
      },
      {
        text: "Learn Vue",
        done: false
      },
      {
        text: "Play around in JSFiddle",
        done: true
      },
      {
        text: "Build something awesome",
        done: true
      }
    ]
  },
  methods: {
    toggle: function(todo) {
      todo.done = !todo.done
    },
    changeProperty1() {
      const val = 'A'
      // this is your code a bit modified
      // defining length (and using it in the comparison) is a
      // bit of optimization, not required
      for (var i = 0, length = this.todos.length; i < length; i++) {
        this.$set(this.todos[i], 'property1', val);
      }
    },
    changeProperty1Again() {
      for (todo of this.todos) {
        if (todo.property1) {
          todo.property1 = 'B'
        }
      }
    }
  },
  created() {

  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <h2>Todos:</h2>
  <ol>
    <li v-for="todo in todos">
      <label>
        <input type="checkbox"
          v-on:change="toggle(todo)"
          v-bind:checked="todo.done">

        <del v-if="todo.done">
          {{ todo.text }}
        </del>
        <span v-else>
          {{ todo.text }}
        </span>
        <span>
          {{ todo.property1 }}
        </span>
      </label>
    </li>
  </ol>
  <button @click="changeProperty1">Click this first</button>
  <button @click="changeProperty1Again">Click this second</button>
</div>

很抱歉,冗长的代码段是我从JSFiddle复制过来的:)

答案 2 :(得分:1)

您只是想向数组中的对象添加新属性。不通过其索引为数组设置新值。您可以执行以下操作:

new Vue({
    el: '#demo',
    data: {
        myArray: [
            {id: 1},
            {id: 2},
            {id: 3},
            {id: 4},
            {id: 5}
        ]
    },
    methods: {
        addProperties() {
            for (var i = 0; i < this.myArray.length; i++) {
                this.$set(this.myArray[i], 'newProperty', 5 - i)
            }
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
    <div v-for="item in myArray" :key="item.id">
        <span>{{item.id}}: </span>
        <span v-if="item.newProperty">{{item.newProperty}}</span>
    </div>
    <button @click="addProperties">Add Properties</button>
</div>

答案 3 :(得分:0)

并不是真正的问题-只是普通的JS:

arr.map(obj => { return {...obj, newProperty: "sameValueAsOthers"}});