Vuejs dan Vue.set (), perbarui larik

93

Saya baru mengenal Vuejs. Membuat sesuatu, tapi saya tidak tahu itu cara yang sederhana / benar.

apa yang saya inginkan

Saya ingin beberapa tanggal dalam sebuah array dan memperbaruinya pada sebuah acara. Pertama saya mencoba Vue.set, tetapi tidak berhasil. Sekarang setelah mengubah item array saya:

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

Saya tidak mendorong () apa pun ke array dan itu akan memperbarui .. Tetapi kadang-kadang item terakhir akan disembunyikan, entah bagaimana ... Saya pikir solusi ini agak hacky, bagaimana saya bisa membuatnya stabil?

Kode sederhana ada di sini:

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>

Johan Hoeksma
sumber

Jawaban:

57

VueJS tidak dapat mengambil perubahan Anda ke status jika Anda memanipulasi array seperti ini.

Seperti yang dijelaskan di Common Beginner Gotchas , Anda harus menggunakan metode array seperti push, splice, atau apa pun dan jangan pernah memodifikasi indeks seperti ini a[2] = 2atau properti .length dari sebuah array.

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>

Borjante
sumber
1
Seperti yang dikatakan di dokumen, $ set hanyalah sebuah .splice () yang cantik. Ini masuk akal karena seperti yang mereka katakan di dokumen Anda harus memodifikasi array menggunakan metodenya.
Borjante
1
Tolong jangan gabungkan indentasi tab dengan indentasi spasi, ukuran tab tampaknya berbeda di aplikasi SE, sehingga sulit untuk membaca kode Anda
Ferrybig
Dalam kasus saya, operator penyebaran ES6 untuk operasi push tidak berfungsi sebagaimana mestinya dengan vue
Mathias S
117

EDIT 2

  • Untuk semua perubahan objek yang membutuhkan penggunaan reaktivitasVue.set(object, prop, value)
  • Untuk mutasi larik, Anda dapat melihat daftar yang didukung saat ini di sini

EDIT 1

Untuk vuex, Anda pasti ingin melakukannya Vue.set(state.object, key, value)


Asli

Jadi hanya untuk orang lain yang datang ke pertanyaan ini. Ini muncul di beberapa titik di Vue 2. * mereka menghapusnya this.items.$set(index, val)demi this.$set(this.items, index, val).

Sambungan masih tersedia dan berikut adalah tautan ke metode mutasi array yang tersedia di tautan vue .

Martin Calvert
sumber
String apa yang harus saya berikan sebagai 'indeks'?
Kokodoko
@Kokodoko dapatkah Anda menjelaskan apa yang Anda coba lakukan? Jika itu adalah array, itu harus menjadi angka untuk indeks. String akan menjadi jika Anda menyetel bidang pada suatu objek.
Martin Calvert
Ah ok, IDE saya bersikeras itu harus menjadi string, pasti ada kesalahan.
Kokodoko
Vue.set bukan untuk vuex. Dan ini. $ Set tidak digunakan lagi.
atilkan
2
@MartinCalvert Dikatakan "saat menambahkan properti ke objek". Itulah tujuan utama Vue.set, tidak hanya terkait dengan vuex. Deprecation, saya membacanya di link tapi sekarang membaca lagi, saya tidak sepenuhnya mengerti. stackoverflow.com/questions/36671106/…
atilkan
11

Seperti yang dinyatakan sebelumnya - VueJS tidak dapat melacak operasi tersebut (penugasan elemen array). Semua operasi yang dilacak oleh VueJS dengan array ada di sini . Tapi saya akan menyalinnya sekali lagi:

  • Dorong()
  • pop ()
  • bergeser()
  • unshift ()
  • sambatan()
  • menyortir()
  • balik()

Selama pengembangan, Anda menghadapi masalah - bagaimana hidup dengan itu :).

push (), pop (), shift (), unshift (), sort () dan reverse () cukup jelas dan membantu Anda dalam beberapa kasus tetapi fokus utamanya terletak di dalam splice () , yang memungkinkan Anda memodifikasi array secara efektif yang akan dilacak oleh VueJs. Jadi saya dapat membagikan beberapa pendekatan, yang paling banyak digunakan dengan array.

Anda perlu mengganti Item di Array:

// 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)

Catatan: jika Anda hanya perlu mengubah bidang item - Anda dapat melakukannya hanya dengan:

this.values[index].itemField = newItemFieldValue

Dan ini akan dilacak oleh VueJS sebagai bidang item (Object) akan dilacak.

Anda perlu mengosongkan array:

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

Sebenarnya Anda dapat melakukan lebih banyak lagi dengan fungsi ini splice () - tautan w3schools Anda dapat menambahkan banyak catatan, menghapus banyak catatan, dll.

Vue.set () dan Vue.delete ()

Vue.set () dan Vue.delete () mungkin digunakan untuk menambahkan bidang ke versi UI data Anda. Misalnya, Anda memerlukan beberapa data atau tanda tambahan yang dihitung dalam objek Anda. Anda dapat melakukan ini untuk objek Anda, atau daftar objek (dalam loop):

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

Dan kirim kembali data yang diedit ke back-end dalam format yang sama dengan melakukan ini sebelum panggilan Axios:

 Vue.delete(plan, 'editEnabled') //(or this.$delete)
Mykola Korol
sumber
0

Satu alternatif - dan pendekatan yang lebih ringan untuk masalah Anda - mungkin, hanya mengedit array sementara dan kemudian menetapkan seluruh array kembali ke variabel Anda. Karena karena Vue tidak memperhatikan item satu per satu, Vue akan melihat seluruh variabel diperbarui.

Jadi Anda ini harus bekerja juga:

var tempArray[];

tempArray = this.items;

tempArray[targetPosition]  = value;

this.items = tempArray;

Ini kemudian juga harus memperbarui DOM Anda.

Geole
sumber