Bu yazıda da pratik olması adına yeni bir proje oluşturacağım. Projemizde yeni componentlar hazırlayacağız ve component içerisinden parent’a (component’ın çağırıldı yer) veri akışını sağlayacağız.
Github’ta paylaşacağım başlangıç seviyesideki proje içerisinde şunlar olacak: Vuetify, Composition API, Props, Emits, Unit Test / Jest (daha sonra). Bu proje sayesinde daha önceden değindiğim parent’tan child’a veri aktarımını da pekiştirmiş olacağız. Ancak, daha önceden Options API ile yaptığımız başlangıcı bu defa Composition API ile yapacağız.
Child – Parent Veri Aktarımı: Github Projesi
Github projesi
Projenin demo adresi
Parent component’tan gelen veriyi Restaurant.vue içerisinde gösteriyoruz. Öncelikle emit konusuyla parent’a veri aktarımını inceleyip sonrasında da diğer konulara göz atabiliriz.
Composition API
<script>
import { defineComponent, reactive, toRefs } from '@vue/composition-api'
export default defineComponent({
name: 'Restaurant',
props: ['restaurant'],
emits: ['select'],
setup(props, { emit }) {
const state = reactive({
loading: false
})
const select = () => {
emit('selected', props.restaurant)
}
return { ...toRefs(state), select }
}
})
</script>
Parent’tan gelen verimizi props array’i içerisinde restaurant ile yakalıyoruz. Sayfa içerisinde artık herhangi bir yerde {{ restaurant }} veya {{ restaurant.title }} ile bu gelen verimizi gösterebiliriz.
emits: [‘select’] ile de select isminde bir emit / method / fonksiyon kullanacağımızı belirtiyoruz.
Burada dikkatimizi çekmesi gereken bir yer daha olabilir. setup() component option’ı içerisine props ve { emit } gönderiyoruz. (emit’in diğer kardeşleri: attr ve slots)
Component İçerisinden Emit Etmek
Restoran card’ı içerisinden SELECT butonuna tıkladığımızda alt taraftaki select methodunu tetikliyoruz. Bunun içerisinde de emit(‘selected’, props.restaurant) yardımıyla parent’a selected isminde bir paket içerisinde props.restaurant verisini gönderiyoruz.
Parent’ta Veriyi Yakalamak
Child component’tan verimizi selected ismiyle gönderdik ve de parent’ta da bunu yakalamamız gerekiyor.
Home.vue içerisinde restaurant component’ını şu şekilde kullanmıştık:
<Restaurant :restaurant="restaurant" :key="restaurant.unique" @selected="selected" />
Buradaki @selected=”selected” veriyi yakalamamıza yarayacak. Tırnaklar içerisinde yer alan “selected” ile de Home.vue içerisindeki selected methodunu çağırmış oluyoruz.
const selected = restaurant => {
state.restaurant = restaurant
state.form = false
setTimeout(() => {
document.querySelector('.selectedRestaurant').scrollIntoView()
}, 0)
}
Üstteki selected methodunda ise şunları yapıyoruz:
- restaurant ismindeki gelen parametredeki verileri state.restaurant içerisine aktarıyoruz.
- Eğer yeni restoran ekleme formu açıksa bunu state.form = false ile kapatıyoruz. İstersek kapatmayabiliriz ancak kötü bir görüntü olmaması için bu şekilde ilerliyoruz.
- Sayfanın konumunu değiştirmek (yukarı doğru çıkmak) için de DOM scrollIntoView() methodunu kullanıyoruz. Yumuşak bir geçiş olması için de scroll-behavior: smooth; stilini kullanıyoruz. Ayrıca, DOM’da henüz selectedRestaurant class’ının belirmeme ihtimaline karşı da settimeout’tan faydalanıyoruz. Çünkü resturant objemiz null iken v-if ile ekranda gösterilmesini engelliyoruz. Sadece dolu olduğu zaman gösteriyoruz.
<v-row v-if="restaurant" class="selectedRestaurant mt-5">
Genel olarak parent’tan child’a ve tam tersi olarak child’tan da parent’a veri aktarımını Vue.js Composition API ile bu şekilde yapabiliyoruz. Eğer tam oturmayan kısımlar varsa, Github’tan projeyi forklayabilir ve minik değişikliklerle neyin ne işe yaradığını daha iyi görebilirsiniz.
Şimdilik özet olarak değinebileceklerimiz bunlar. Bir sonraki yazıda child componentlar arasında veri aktarımına da değinmeyi düşünüyorum. Bir de projede test klasörü yer almasına rağmen şu anda boş görünüyor. Belki siz bu yazıyı gördüğünüzde testlerimiz de yazılmış olur, ne dersiniz? :)