Vuejs i Vue.set (), aktualizacja tablicy

93

Jestem nowy w Vuejs. Zrobiłem coś, ale nie wiem, że to prosty / właściwy sposób.

czego chcę

Chcę mieć jakieś daty w tablicy i zaktualizować je na wydarzeniu. Najpierw wypróbowałem Vue.set, ale nie wyszło. Teraz po zmianie pozycji mojej tablicy:

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

Nic nie wciskam () do tablicy i to się zaktualizuje .. Ale czasami ostatnia pozycja będzie ukryta, jakoś ... Myślę, że to rozwiązanie jest trochę zepsute, jak mogę to naprawić?

Oto prosty kod:

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
źródło

Odpowiedzi:

57

VueJS nie może odebrać zmian stanu, jeśli manipulujesz tablicami w ten sposób.

Jak wyjaśniono w artykule Typowe problemy dla początkujących , należy używać metod tablicowych, takich jak push, splice lub cokolwiek innego i nigdy nie modyfikować takich indeksów a[2] = 2ani właściwości .length tablicy.

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
źródło
1
Jak powiedziano w dokumentacji, $ set to po prostu ładna .splice (). Ma to sens, ponieważ tak jak mówią w dokumentacji, powinieneś zmodyfikować tablicę używając jej metod.
Borjante
1
Pls nie łączą wcięć tabulatorów z wcięciami spacji, rozmiar tabulatora jest najwyraźniej inny w aplikacji SE, co utrudnia odczytanie kodu
Ferrybig
W moim przypadku operator spreadu ES6 dla operacji push nie działa poprawnie z vue
Mathias S
117

EDYCJA 2

  • Dla wszystkich zmian obiektów, które wymagają użycia reaktywnościVue.set(object, prop, value)
  • W przypadku mutacji tablicowych możesz spojrzeć na aktualnie obsługiwaną listę tutaj

EDYCJA 1

Dla vuex będziesz chciał to zrobić Vue.set(state.object, key, value)


Oryginał

Więc tylko dla innych, którzy przychodzą do tego pytania. Pojawia się w pewnym momencie w Vue 2. * usunęli this.items.$set(index, val)na korzyśćthis.$set(this.items, index, val) .

Splice jest nadal dostępne, a tutaj jest link do metod mutacji tablicowych dostępnych w vue link .

Martin Calvert
źródło
Jaki ciąg muszę podać jako „indeks”?
Kokodoko,
@Kokodoko Czy możesz wyjaśnić, co próbujesz zrobić? Jeśli jest to tablica, powinna to być liczba dla indeksu. Ciąg byłby taki, jeśli ustawiasz pole na obiekcie.
Martin Calvert,
Ach ok, moje IDE nalegało, że to musi być ciąg, musi być usterka.
Kokodoko
Vue.set nie jest przeznaczony dla vuex. I to. $ Set jest przestarzałe.
atilkan
2
@MartinCalvert Mówi „podczas dodawania właściwości do obiektu”. To jest główny cel Vue.set, nie związany tylko z vuex. Wycofanie, przeczytałem to pod linkiem, ale teraz czytam ponownie, nie do końca rozumiem. stackoverflow.com/questions/36671106/ ...
atilkan
11

Jak wspomniano wcześniej - VueJS po prostu nie może śledzić tych operacji (przypisywanie elementów tablicy). Wszystkie operacje śledzone przez VueJS z tablicą są tutaj . Ale jeszcze raz je skopiuję:

  • Pchać()
  • Muzyka pop()
  • Zmiana()
  • unshift ()
  • splatać()
  • sortować()
  • odwrócić()

W trakcie tworzenia stajesz przed problemem - jak z tym żyć :).

push (), pop (), shift (), unshift (), sort () i reverse () są dość proste i pomagają w niektórych przypadkach, ale główny nacisk kładzie się na splice () , co pozwala skutecznie modyfikować tablicę który byłby śledzony przez VueJs. Mogę więc podzielić się niektórymi podejściami, które są najczęściej używane w pracy z tablicami.

Musisz zamienić element w tablicy:

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

Uwaga: jeśli potrzebujesz tylko zmodyfikować pole przedmiotu - możesz to zrobić po prostu:

this.values[index].itemField = newItemFieldValue

Byłoby to śledzone przez VueJS w miarę śledzenia pól elementu (obiektu).

Musisz opróżnić tablicę:

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

Właściwie możesz zrobić znacznie więcej dzięki tej funkcji splice () - łącze w3schools Możesz dodać wiele rekordów, usunąć wiele rekordów itp.

Vue.set () i Vue.delete ()

Vue.set () i Vue.delete () mogą służyć do dodawania pól do wersji danych w interfejsie użytkownika. Na przykład potrzebujesz dodatkowych obliczonych danych lub flag w swoich obiektach. Możesz to zrobić dla swoich obiektów lub listy obiektów (w pętli):

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

I wyślij edytowane dane z powrotem do zaplecza w tym samym formacie, robiąc to przed wywołaniem Axios:

 Vue.delete(plan, 'editEnabled') //(or this.$delete)
Mykoła Korol
źródło
0

Jedną z alternatyw - i lżejszym podejściem do problemu - może być po prostu tymczasowa edycja tablicy, a następnie przypisanie całej tablicy z powrotem do zmiennej. Ponieważ Vue nie obserwuje poszczególnych elementów, będzie obserwować aktualizację całej zmiennej.

Więc to powinno również działać:

var tempArray[];

tempArray = this.items;

tempArray[targetPosition]  = value;

this.items = tempArray;

Powinno to również zaktualizować Twój DOM.

Geole
źródło