Vue'da Reaktivite
Yayınlanan: 2022-03-10Bu 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.
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