Używam Vue od jakiegoś czasu i moje doświadczenie zawsze było metodą, która ponownie obliczy, jeśli podstawowe dane reaktywne zostaną zaktualizowane. Napotkałem sprzeczne informacje na temat SO:
- Próbowałem odpowiedzieć na to pytanie i wielokrotnie mówiono mi, że tak nie jest.
- Przyjęta tutaj odpowiedź wskazuje, że „[metoda] zostanie oceniona tylko wtedy, gdy ją wyraźnie wywołasz”.
Przeszukałem dokumenty i nie zauważyłem niczego niesamowicie wyraźnego.
Jeśli nie są reaktywne, to dlaczego ten przykład działa?
<ul>
<li v-for="animal in animals" :key="animal.id">
<span v-if="isAwesome(animal)">{{ animal.name }}</span>
</li>
</ul>
export default {
data() {
return {
awesomeAnimalIds: [],
animals: [
{ id: 1, name: 'dog' },
{ id: 5, name: 'cat' },
{ id: 9, name: 'fish' },
],
};
},
created() {
setTimeout(() => {
this.awesomeAnimalIds.push(5);
}, 1000);
setTimeout(() => {
this.awesomeAnimalIds.push(9);
}, 2000);
},
methods: {
isAwesome(animal) {
return this.awesomeAnimalIds.includes(animal.id);
},
},
};
I byłoby naprawdę lubią mieć ostateczne i wyczerpującą odpowiedź, że społeczność ta może dotyczyć.
Odpowiedzi:
Na podstawie tego, jak śledzone są zmiany z dokumentów, oto, co się dzieje:
Dla instancji komponentu tworzony jest specjalny obserwator, który określa, kiedy wymagane jest ponowne renderowanie.
Vue konwertuje wszystkie właściwości
data
na getters i setters.isAwesome
z szablonu jest wywoływane polecenieisAwesome
getter forawesomeAnimalIds
.awesomeAnimalIds
poladata
.awesomeAnimalIds
jest aktualizowany, co wywołujeawesomeAnimalIds
setera.data
pola, które otrzymało powiadomienie, uruchamiane jest ponowne renderowanie.Na podstawie powyższego i powyższego przykładu możemy wyciągnąć następujące wnioski:
Istnieje powszechne nieporozumienie, że metody są „wywoływane tylko raz” lub „odpalają i zapominają”, gdy są wywoływane z szablonu. Oczywiście nie zawsze tak jest, ponieważ metody mogą ustalić zależność reaktywną .
Kiedy więc powinniśmy użyć obliczonej właściwości vs metody?
Zobacz sekcję przewodnika dotyczącą buforowania obliczeniowego a metod . Oto moje zdanie na ten temat:
fetch
od nich.źródło
Nie, metody nie są reaktywne. Tylko dane mogą być reaktywne w Vue.
ALE ważne jest, aby zrozumieć, jak działa Vue ...
data()
członków (robi to cały czas, nie tylko podczas pierwszego renderowania). Jeśli jakiekolwiek dane są dostępne podczas renderowania, Vue wie, że zawartość tego elementu danych wpływa na wynik renderowania.Nie ma znaczenia, czy odwołujesz się bezpośrednio do członka danych, używasz go w
computed
lub wmethod
. Jeśli dane zostaną „dotknięte” podczas renderowania, zmiana danych spowoduje ponowne renderowanie w przyszłości ...źródło
To bardzo interesujący przypadek.
Z tego, co przeczytałem i z mojego doświadczenia mogę powiedzieć, że: Nie, metody nie są z natury reaktywne. Metoda musi zostać jawnie wywołana, aby mogła zostać wykonana.
Ale jak mogę wyjaśnić twoją sprawę? Umieściłem twój kod w piaskownicy i na pewno, kiedy wpychasz id do tablicy, szablon aktualizuje się, aby wyświetlić nazwę zwierzęcia. Oznaczałoby to pewną reaktywność. Co daje?
Cóż, przeprowadziłem eksperyment. Dodałem prostą
div
do każdej pętli, która generuje losową liczbę po wygenerowaniu.I zobaczyłem, że za każdym razem, gdy nowy identyfikator jest wpychany do tablicy, wszystkie losowe liczby będą się zmieniać. Jest to klucz do zrozumienia, dlaczego „wydaje się”, jakby metoda
isAwesome
była reaktywna.W jakiś sposób, gdy nowy identyfikator jest wypychany do tablicy, Vue ponownie renderuje pętlę całkowicie, tym samym ponownie wykonując metody. Nie potrafię wyjaśnić, dlaczego Vue ponownie przetwarza całą pętlę, co wymagałoby dalszych badań.
Aby odpowiedzieć na twoje pytanie.
isAwesome
nie jest reaktywny, jest jedynie iluzją stworzoną przez ponowne renderowanie pętli.źródło
update
co powoduje are-render
i uruchamia wszelkie metody powiązane w szablonie