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>

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>


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 .


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)

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.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.