Staram się zrozumieć, jak prawidłowo obserwować niektóre odmiany rekwizytów. Mam komponent nadrzędny (pliki .vue), który odbiera dane z wywołania ajax, umieszczam dane w obiekcie i używam go do renderowania komponentu podrzędnego za pomocą dyrektywy v-for, poniżej uproszczenia mojej implementacji:
<template>
<div>
<player v-for="(item, key, index) in players"
:item="item"
:index="index"
:key="key"">
</player>
</div>
</template>
... a następnie wewnątrz <script>
tagu:
data(){
return {
players: {}
},
created(){
let self = this;
this.$http.get('../serv/config/player.php').then((response) => {
let pls = response.body;
for (let p in pls) {
self.$set(self.players, p, pls[p]);
}
});
}
obiekty przedmiotów są takie:
item:{
prop: value,
someOtherProp: {
nestedProp: nestedValue,
myArray: [{type: "a", num: 1},{type: "b" num: 6} ...]
},
}
Teraz w komponencie mojego „odtwarzacza” mojego dziecka próbuję obserwować zmiany właściwości dowolnego przedmiotu i używam:
...
watch:{
'item.someOtherProp'(newVal){
//to work with changes in "myArray"
},
'item.prop'(newVal){
//to work with changes in prop
}
}
Działa, ale wydaje mi się to trochę trudne i zastanawiałem się, czy to właściwy sposób, aby to zrobić. Moim celem jest wykonywanie pewnych działań za każdym razem, gdy prop
zmieniają się lub myArray
otrzymują nowe elementy lub zmiany w istniejących. Wszelkie sugestie będą mile widziane.
źródło
"item.someOtherProp": function (newVal, oldVal){
zgodnie z sugestią @Ron.keys
wnętrzu obiektu? Przykład:"item.*": function(val){...}
Odpowiedzi:
Możesz do tego użyć głębokiego obserwatora :
Spowoduje to teraz wykrycie wszelkich zmian w obiektach w
item
tablicy i dodatków do samej tablicy (w przypadku użycia z Vue.set ). Oto JSFiddle: http://jsfiddle.net/je2rw3rs/EDYTOWAĆ
Jeśli nie chcesz obserwować każdej zmiany w obiekcie najwyższego poziomu, a po prostu chcesz mniej niezręczną składnię do bezpośredniego oglądania zagnieżdżonych obiektów, możesz po prostu obejrzeć
computed
:Oto JSFiddle: http://jsfiddle.net/oa07r5fw/
źródło
computed
zamiast tego obejrzeć : jsfiddle.net/c52nda7xwatch: { 'item.foo' : function(newVal, oldVal) { // do work here }}
całkiem sprytne. Kocham Vue!Kolejne dobre i nieco bardziej eleganckie podejście wygląda następująco:
(Nauczyłem się tego podejścia od @peerbolte w komentarzu tutaj )
źródło
ES5
składni. Możemy oczywiście argumentować, żeES2015 method definition
sam w sobie nie jest zbyt elegancki, ale w pewnym sensie pomija sens pytania, a mianowicie , jak uniknąć zawijania nazwy, to cytaty. Domyślam się, że większość ludzi zastanawia się nad pierwotnym pytaniem, które już zawiera odpowiedź, i faktycznie szuka czegoś, co, jak mówisz, nie jest zbyt dobrze udokumentowane,Głęboki wgląd VueJ w obiekty potomne
źródło
Możesz użyć „obserwatora dynamicznego”:
$watch
Zwraca unwatch funkcję, która będzie oglądać jeśli to się nazywa.Możesz także skorzystać z
deep
opcji:Proszę zajrzeć do dokumentów
źródło
Note that you should not use an arrow function to define a watcher (e.g. searchQuery: newValue => this.updateAutocomplete(newValue)). The reason is arrow functions bind the parent context, so this will not be the Vue instance as you expect and this.updateAutocomplete will be undefined.
Nie widzę tu wspomnianego, ale można również użyć
vue-property-decorator
wzorca, jeśli rozszerzasz swojąVue
klasę.źródło
Innym sposobem na dodanie tego, że „włamałem się” do tego rozwiązania, było zrobienie tego: ustawiłem osobną
computed
wartość, która po prostu zwróci wartość zagnieżdżonego obiektu.źródło
Mój problem z zaakceptowaną odpowiedzią użycia
deep: true
polega na tym, że podczas głębokiego oglądania tablicy nie mogę łatwo zidentyfikować, który element tablicy zawiera zmianę. Jedynym jasnym rozwiązaniem, jakie znalazłem, jest ta odpowiedź, która wyjaśnia, jak utworzyć komponent, abyś mógł oglądać każdy element tablicy osobno.źródło
oldVal
inewVal
oba odnoszą się do tego samego obiektu, więc są takie same). Intencją adeep watcher
jest zrobienie czegoś, gdy zmienią się wartości, na przykład wyemitowanie zdarzenia, wywołanie ajax itp. W przeciwnym razie prawdopodobnie potrzebujesz komponentu, jak wskazano w odpowiedzi Mani.Śledzenie pojedynczych zmienionych pozycji na liście
Jeśli chcesz oglądać wszystkie elementy na liście i wiedzieć, który element na liście się zmienił, możesz skonfigurować niestandardowe obserwatory dla każdego elementu osobno, na przykład:
Jeśli lista nie jest wypełniona od razu (jak w pierwotnym pytaniu), możesz przenieść logikę
created
do dowolnego miejsca, np. Wewnątrz.then()
bloku.Oglądanie zmieniającej się listy
Jeśli twoja lista sama się aktualizuje, aby mieć nowe lub usunięte elementy, opracowałem przydatny wzór, który „płytki” obserwuje samą listę i dynamicznie obserwuje / odblokowuje elementy, gdy lista się zmienia:
źródło
Żadna odpowiedź nie działała dla mnie. W rzeczywistości, jeśli chcesz oglądać zagnieżdżone dane, a komponenty są wywoływane wiele razy. Są więc nazywani różnymi rekwizytami, aby je zidentyfikować. Na przykład
<MyComponent chart="chart1"/> <MyComponent chart="chart2"/>
moim obejściem jest utworzenie dodatkowej zmiennej stanu Vuex, którą ręcznie aktualizuję, aby wskazać właściwość, która była ostatnio aktualizowana.Oto przykład implementacji Vuex.ts:
W dowolnej funkcji komponentu, aby zaktualizować sklep:
Teraz na dowolnym komponencie, aby uzyskać aktualizację:
źródło