Как установить свойство $ для нескольких объектов в массиве, но сохранить индивидуальную реактивность в vue js

В моем случае у меня есть массив data с несколькими объектами.

data() {
 return {
   selected: 0,
   presetData: [true, true, true],
   data: [
     {
       name: "name 1"
     },
     {
       name: "name 2"
     }
   ]
 };

},

затем я хочу вставить каждый объект в data, как показано ниже

setNewData() {
  this.data.forEach((o, i) => {
    this.$set(this.data[i], "time", this.presetData);
  });
},

теперь мой с presetData вставленным в data будет выглядеть так

data: [
    {
      name: "name 1",
      time: [true, true, true]
    },
    {
      name: "name 2",
      time: [true, true, true]
    }
  ]

и я хочу изменить отдельное свойство time каждого объекта, которое я использую примерно так:

$set(item.time,selected,true)

Моя проблема

моя проблема в том, что это изменит свойство time обоих объектов. Как мне сначала правильно нажать/установить presetData в data, ниже весь мой код, извините, я очень новичок в программировании, вот ссылка на jsfiddle

    new Vue({
  el: "#app",
  data() {
    return {
      selected: 0,
      presetData: [true, true, true],
      data: [
        {
          name: "name 1",
        },
        {
          name: "name 2",
        }
      ]
    };
  },
  methods: {
    setNewData() {
      this.data.forEach((o, i) => {
        this.$set(this.data[i], "time", this.presetData);
      });
    },
  }
})

  <div id="app">
<button @click="setNewData">Set Data</button>
<br>
<br>
<select v-model="selected">
  <option>0</option>
  <option>1</option>
  <option>2</option>
</select>
<div v-for="item in data" :key="item.id">
  <p>{{item.name}}</p>
  <p>{{item.time}}</p>
  <button @click="$set(item.time,selected,true)">Change True</button>
  <button @click="$set(item.time,selected,false)">Change False</button>
</div>

person aleng    schedule 01.09.2020    source источник


Ответы (1)


Это проблема ссылки на объект. Каждое из ваших свойств time ссылается на один и тот же массив (presetData). Вы можете избавиться от этой проблемы, сделав мелкие копии через синтаксис распространения.

Вы также можете избежать Vue.set() при назначении новых data, используя тот же метод.

setNewData() {
  this.data = this.data.map(d => ({
    ...d, // create a shallow copy of each data item
    time: [...this.presetData] // add "time" as a shallow copy of presetData
  }))
},

Чтобы изменить отдельные элементы массива в свойстве time, вам нужно продолжать использовать Vue.set(), т.е.

this.$set(item.time, selected, true)
person Phil    schedule 01.09.2020
comment
большое спасибо, да ссылка на объект. Как вы думаете, я должен изменить свой вопрос? - person aleng; 01.09.2020
comment
@aleng нет, твой вопрос в порядке - person Phil; 01.09.2020