Vue'da Reaktivite

Yayınlanan: 2022-03-10
Hızlı özet ↬ Tepkisellik, bir değişkenin (dizi, dize, sayı, nesne, vb.) değeri veya başvuruda bulunduğu herhangi bir değişken bildirimden sonra değiştirildiğinde güncelleme yeteneğidir.

Bu yazıda, Vue'daki reaktiviteye, nasıl çalıştığına ve yeni oluşturulan metotları ve fonksiyonları kullanarak nasıl reaktif değişkenler oluşturabileceğimize bakacağız. Bu makale, Vue 2.x'in nasıl çalıştığını iyi anlayan ve yeni Vue 3'ü tanımak isteyen geliştiricilere yöneliktir.

Bu konuyu daha iyi anlamak için basit bir uygulama oluşturacağız. Bu uygulamanın kodu GitHub'da bulunabilir.

Varsayılan olarak, JavaScript reaktif değildir . Bu, boy değişkenini oluşturup uygulamamızın A bölümünde ona başvurursak, ardından B bölümünde boy değiştirmeye devam edersek, A bölümünün boy yeni değeriyle güncellenmeyeceği anlamına gelir.

 let framework = 'Vue'; let sentence = `${framework} is awesome`; console.log(sentence) // logs "Vue is awesome" framework = 'React'; console.log(sentence) //should log "React is awesome" if 'sentence' is reactive.

Yukarıdaki snippet, JavaScript'in reaktif olmayan doğasının mükemmel bir örneğidir - bu nedenle, değişikliğin neden sentence değişkenine yansıtılmadığı.

Vue 2.x'te props , computed ve data() öğelerinin tümü, bu tür bileşenler oluşturulduğunda data mevcut olmayan özellikler dışında, varsayılan olarak reaktifti. Bu, DOM'a bir bileşen enjekte edildiğinde, yalnızca bileşenin data nesnesindeki mevcut özelliklerin, bu tür özellikler değiştiğinde ve değiştiğinde bileşenin güncellenmesine neden olacağı anlamına gelir.

Dahili olarak Vue 3, bu özelliklerin reaktif olduğundan emin olmak için Proxy nesnesini (bir ECMAScript 6 özelliği) kullanır, ancak yine de Internet Explorer desteği (ECMAScript 5) için Vue 2'den Object.defineProperty kullanma seçeneği sunar. Bu yöntem, doğrudan bir nesne üzerinde yeni bir özellik tanımlar veya bir nesne üzerindeki mevcut bir özelliği değiştirir ve nesneyi döndürür.

İlk bakışta ve çoğumuz tepkiselliğin Vue'da yeni olmadığını zaten bildiğimizden, bu özellikleri kullanmak gereksiz görünebilir, ancak birkaç uygulamada yeniden kullanılabilir işlevlere sahip büyük bir uygulamayla uğraşırken Seçenekler API'sinin sınırlamaları vardır. uygulamanın bölümleri. Bu amaçla, bir kod tabanının okunmasını ve bakımını daha kolay hale getirmek için soyutlama mantığına yardımcı olmak için yeni Composition API tanıtıldı. Ayrıca, yeni özelliklerden ve yöntemlerden herhangi birini kullanarak veri türünden bağımsız olarak artık herhangi bir değişkeni kolayca reaktif hale getirebiliriz.

Composition API için giriş noktası işlevi gören setup seçeneğini kullandığımızda, setup yürütüldüğünde bileşen örneği henüz oluşturulmadığı için data nesnesine, computed özelliklere ve methods erişilemez. Bu, setup bu özelliklerden herhangi birinde yerleşik reaktiviteden yararlanmayı imkansız hale getirir. Bu derste, bunu yapabileceğimiz tüm yolları öğreneceğiz.

Atlamadan sonra daha fazlası! Aşağıdan okumaya devam edin ↓

Reaktif Yöntem

Belgelere göre, Vue Vue.observable() 'ın eşdeğeri olan reactive yöntem, tüm özellikleri reaktif olan bir nesne oluşturmaya çalışırken (Seçenekler'deki data nesnesi gibi) yararlı olabilir. API). Başlık altında, Seçenekler API'sindeki data nesnesi, içindeki tüm özellikleri reaktif hale getirmek için bu yöntemi kullanır.

Ancak bunun gibi kendi reaktif nesnemizi yaratabiliriz:

 import { reactive } from 'vue' // reactive state let user = reactive({ "id": 1, "name": "Leanne Graham", "username": "Bret", "email": "[email protected]", "address": { "street": "Kulas Light", "suite": "Apt. 556", "city": "Gwenborough", "zipcode": "92998-3874", "geo": { "lat": "-37.3159", "lng": "81.1496" } }, "phone": "1-770-736-8031 x56442", "website": "hildegard.org", "company": { "name": "Romaguera-Crona", "catchPhrase": "Multi-layered client-server neural-net", "bs": "harness real-time e-markets" }, "cars": { "number": 0 } })

Burada Vue'dan reactive metodu içe aktardık ve ardından bu fonksiyona argüman olarak değerini ileterek user değişkenimizi bildirdik. Bunu yaparken user reaktif hale getirdik ve bu nedenle, şablonumuzda user kullanırsak ve bu nesnenin nesnesi veya bir özelliğinin değişmesi gerekiyorsa, bu değer bu şablonda otomatik olarak güncellenecektir.

ref

Nesneleri reaktif hale getirmek için bir yöntemimiz olduğu gibi, diğer bağımsız ilkel değerleri (dizeler, booleanlar, tanımsız değerler, sayılar, vb.) ve dizileri reaktif hale getirmek için de birine ihtiyacımız var. Geliştirme sırasında, reaktif olmalarına ihtiyaç duyarken bu diğer veri türleri ile çalışırdık. Aklımıza gelen ilk yaklaşım, reactive kullanmak ve reaktif yapmak istediğimiz değişkenin değerini girmek olabilir.

 import { reactive } from 'vue' const state = reactive({ users: [], });

reactive , derin reaktif dönüşüme sahip olduğundan, bir mülk olarak user da reaktif olacaktır, böylece hedefimize ulaşmış oluruz; bu nedenle, user böyle bir uygulamanın şablonunda kullanıldığı her yerde her zaman güncelleme yapar. Ancak ref özelliği ile, herhangi bir veri tipine sahip herhangi bir değişkeni, o değişkenin değerini ref geçirerek reaktif hale getirebiliriz. Bu yöntem nesneler için de çalışır, ancak nesneyi reactive yöntemin kullanıldığı duruma göre bir düzey daha derine yerleştirir.

 let property = { rooms: '4 rooms', garage: true, swimmingPool: false } let reactiveProperty = ref(property) console.log(reactiveProperty) // prints { // value: {rooms: "4 rooms", garage: true, swimmingPool: false} // }

Başlık altında, ref kendisine iletilen bu argümanı alır ve onu bir value anahtarına sahip bir nesneye dönüştürür. Bu, değişkenimize variable.value çağırarak erişebileceğimizi ve aynı şekilde onu çağırarak da değerini değiştirebileceğimizi gösterir.

 import {ref} from 'vue' let age = ref(1) console.log(age.value) //prints 1 age.value++ console.log(age.value) //prints 2

Bununla, bileşenimize ref aktarabilir ve reaktif bir değişken oluşturabiliriz:

 <template> <div class="home"> <form @click.prevent=""> <table> <tr> <th>Name</th> <th>Username</th> <th>email</th> <th>Edit Cars</th> <th>Cars</th> </tr> <tr v-for="user in users" :key="user.id"> <td>{{ user.name }}</td> <td>{{ user.username }}</td> <td>{{ user.email }}</td> <td> <input type="number" name="cars" v-model.number="user.cars.number" /> </td> <td> <cars-number :cars="user.cars" /> </td> </tr> </table> <p>Total number of cars: {{ getTotalCars }}</p> </form> </div> </template> <script> // @ is an alias to /src import carsNumber from "@/components/cars-number.vue"; import axios from "axios"; import { ref } from "vue"; export default { name: "Home", data() { return {}; }, setup() { let users = ref([]); const getUsers = async () => { let { data } = await axios({ url: "data.json", }); users.value = data; }; return { users, getUsers, }; }, components: { carsNumber, }, created() { this.getUsers(); }, computed: { getTotalCars() { let users = this.users; let totalCars = users.reduce(function(sum, elem) { return sum + elem.cars.number; }, 0); return totalCars; }, }; </script>

Burada, bileşenimizde reaktif bir users değişkeni oluşturmak için ref içe aktardık. Daha sonra public klasördeki bir JSON dosyasından veri almak için axios içe aktardık ve daha sonra oluşturacağımız carsNumber bileşenimizi içe aktardık. Yaptığımız sonraki şey, users JSON dosyamızdan gelen yanıt değiştiğinde güncelleme yapabilmeleri için ref yöntemini kullanarak reaktif bir users değişkeni oluşturmaktı.

Ayrıca, axios kullanarak JSON dosyamızdan users dizisini getiren bir getUser işlevi oluşturduk ve bu istekten gelen değeri users değişkenine atadık. Son olarak, şablon bölümünde değiştirdiğimiz gibi, kullanıcılarımızın sahip olduğu toplam araba sayısını hesaplayan hesaplanmış bir özellik oluşturduk.

Şablon bölümünde veya setup() dışında döndürülen ref özelliklerine erişirken, bunların otomatik olarak yüzeysel olarak açılmadığını not etmek önemlidir. Bu, bir nesne olan .value refs anlamına gelir. Users bir dizi olduğundan, users.value içinde users users getTotalCars

Şablon bölümünde, bir <cars-number /> bileşeniyle birlikte her kullanıcının bilgilerini gösteren bir tablo görüntüledik. Bu bileşen, her kullanıcının satırında sahip oldukları araba sayısı olarak görüntülenen bir cars desteğini kabul eder. Bu değer, kullanıcı nesnesinde cars değeri değiştiğinde güncellenir; bu, Seçenekler API'si ile çalışıyor olsaydık, data nesnesi veya computed özellik tam olarak böyle çalışırdı.

toRefs

Composition API'yi kullandığımızda, setup işlevi iki argümanı kabul eder: props ve context . Bu props , bileşenden setup() öğesine iletilir ve bileşenin sahip olduğu aksesuarlara bu yeni API içinden erişmeyi mümkün kılar. Bu yöntem özellikle yararlıdır çünkü nesnelerin reaktivitesini kaybetmeden yok edilmesini sağlar.

 <template> <p>{{ cars.number }}</p> </template> <script> export default { props: { cars: { type: Object, required: true, }, gender: { type: String, required: true, }, }, setup(props) { console.log(props); // prints {gender: "female", cars: Proxy} }, }; </script> <style></style>

Reaktivitesini korurken Composition API'deki props bir nesne olan bir değeri kullanmak için toRefs . Bu yöntem, reaktif bir nesneyi alır ve onu, orijinal reaktif nesnenin her özelliğinin bir ref olduğu düz bir nesneye dönüştürür. Bunun anlamı, cars pervane…

 cars: { number: 0 }

… şimdi bu olacaktı:

 { value: cars: { number: 0 }

Bununla, reaktifliğini korurken kurulum API'sinin herhangi bir bölümündeki cars kullanabiliriz.

 setup(props) { let { cars } = toRefs(props); console.log(cars.value); // prints {number: 0} },

Bu yeni değişkeni Composition API'nin saatini kullanarak watch ve bu değişikliğe istediğimiz gibi tepki verebiliriz.

 setup(props) { let { cars } = toRefs(props); watch( () => cars, (cars, prevCars) => { console.log("deep ", cars.value, prevCars.value); }, { deep: true } ); }

toRef

Karşılaşabileceğimiz bir diğer yaygın kullanım durumu, mutlaka bir nesne olmayan, daha çok ref ile çalışan veri türlerinden biri olan bir değeri (dizi, sayı, dize, boolean, vb.) iletmektir. toRef ile, kaynak reaktif nesneden bir reaktif özellik (yani ref ) oluşturabiliriz. Bunu yapmak, özelliğin reaktif kalmasını sağlar ve ana kaynak değiştiğinde güncellenir.

 const cars = reactive({ Toyota: 1, Honda: 0 }) const NumberOfHondas = toRef(state, 'Honda') NumberOfHondas.value++ console.log(state.Honda) // 1 state.Honda++ console.log(NumberOfHondas.value) // 2

Burada, Toyota ve Honda özelliklerine sahip reactive yöntemi kullanarak reaktif bir nesne oluşturduk. Honda reaktif bir değişken oluşturmak için toRef de kullandık. Yukarıdaki örnekten, Honda reaktif cars nesnesini veya NumberOfHondas kullanarak güncellediğimizde, değerin her iki durumda da güncellendiğini görebiliriz.

Bu yöntem, kaynağıyla bağlantısını sürdürmesi ve diziler, diziler ve sayılar için kullanılabilmesi açısından yukarıda ele aldığımız toRefs yöntemine benzer ve yine de ondan çok farklıdır. toRefs farklı olarak, oluşturma sırasında mülkün kaynağında olup olmadığı konusunda endişelenmemize gerek yoktur, çünkü bu özellik, bu ref oluşturulduğu anda mevcut değilse ve bunun yerine null değerini döndürürse, yine de depolanır. geçerli bir özellik olarak, bir watcher formu yerleştirilmiş, böylece bu değer değiştiğinde, toRef kullanılarak oluşturulan bu ref de güncellenecektir.

Bu yöntemi props reaktif bir özellik oluşturmak için de kullanabiliriz. Bu şuna benzer:

 <template> <p>{{ cars.number }}</p> </template> <script> import { watch, toRefs, toRef } from "vue"; export default { props: { cars: { type: Object, required: true, }, gender: { type: String, required: true, }, }, setup(props) { let { cars } = toRefs(props); let gender = toRef(props, "gender"); console.log(gender.value); watch( () => cars, (cars, prevCars) => { console.log("deep ", cars.value, prevCars.value); }, { deep: true } ); }, }; </script>

Burada, props alınan gender özelliğine dayalı olacak bir ref oluşturduk. Bu, belirli bir bileşenin pervanesi üzerinde ekstra işlemler yapmak istediğimizde işe yarar.

Çözüm

Bu makalede, Vue 3'te yeni tanıtılan bazı yöntem ve işlevleri kullanarak Vue'daki reaktivitenin nasıl çalıştığına baktık. Reaktivitenin ne olduğuna ve Vue'nin bunu başarmak için sahne arkasında Proxy nesnesini nasıl kullandığına bakarak başladık. Ayrıca, reaktif kullanarak reactive nesneleri nasıl oluşturabileceğimize ve ref kullanarak reaktif özellikleri nasıl oluşturabileceğimize baktık.

Son olarak, her bir özelliği orijinal nesnenin karşılık gelen özelliğine işaret eden bir ref olan reaktif nesnelerin düz nesnelere nasıl dönüştürüleceğine baktık ve reaktif bir kaynak nesnede bir özellik için nasıl ref oluşturulacağını gördük.

Diğer Kaynaklar

  • "Proxy" (nesne), MDN Web Dokümanları
  • "Reaktivitenin Temelleri", Vue.js
  • "Refler", Vue.js
  • setup İçinde Yaşam Döngüsü Kanca Kaydı ”, Vue.js