Cara Melewati Data Antar Komponen Di Vue.js

Diterbitkan: 2022-03-10
Ringkasan cepat Dengan begitu banyak cara berbeda untuk berbagi data di seluruh komponen, Anda harus mengetahui teknik mana yang terbaik untuk situasi Anda. Mari kita menganalisis tiga cara paling umum untuk melewatkan data di VueJS.

Berbagi data antar komponen adalah salah satu fungsi inti VueJS. Ini memungkinkan Anda merancang proyek yang lebih modular, mengontrol cakupan data, dan membuat aliran data alami di seluruh aplikasi Anda.

Kecuali jika Anda membuat seluruh aplikasi Vue dalam satu komponen (yang tidak masuk akal), Anda akan menghadapi situasi di mana Anda perlu berbagi data antar komponen.

Pada akhir tutorial ini, Anda akan mengetahui tiga cara untuk menyelesaikannya.

  • Menggunakan alat peraga untuk berbagi data dari orang tua ke anak,
  • Memancarkan acara khusus untuk membagikan data dari anak ke orang tua,
  • Menggunakan Vuex untuk membuat status bersama tingkat aplikasi.

Oke — mari kita langsung ke dalamnya!

Membangun Aplikasi Dengan Nuxt

Dengan Spotify, teman Anda dapat melihat apa yang Anda tuju. Bagaimana jika seluruh Internet dapat mengalami algo-ritme Anda juga? Pelajari cara membuat aplikasi Anda sendiri untuk membagikan apa yang Anda dengarkan di Spotify menggunakan Vue.js dan Nuxt. Baca artikel terkait →

Lebih banyak setelah melompat! Lanjutkan membaca di bawah ini

1. Menggunakan Alat Peraga Untuk Berbagi Data Dari Orang Tua Ke Anak

Alat peraga VueJS adalah cara paling sederhana untuk berbagi data antar komponen. Alat peraga adalah atribut khusus yang dapat kita berikan kepada suatu komponen. Kemudian, dalam template kita, kita dapat memberikan nilai atribut tersebut dan — BAM — kita meneruskan data dari komponen induk ke komponen turunan!

Misalnya, katakanlah kita sedang mengerjakan halaman profil pengguna dan ingin komponen anak menerima prop nama pengguna. Kita akan membutuhkan dua komponen.

  1. Komponen anak menerima prop, sebut saja ini AccountInfo.vue .
  2. Komponen induk yang meneruskan prop, sebut saja ProfilePage.vue ini.

Di dalam AccountInfo.vue , kita dapat mendeklarasikan props yang diterimanya menggunakan opsi props. Jadi, di dalam opsi komponen, mari kita buat seperti berikut ini.

 // AccountInfo.vue <template> <div id='account-info'> {{username}} </div> </template> <script> export default { props: ['username'] } </script>

Kemudian, untuk benar-benar meneruskan data dari induknya ( ProfilePage.vue ), kami meneruskannya seperti atribut khusus.

 // ProfilePage.vue <account-info username='matt' />

Sekarang jika kita memuat halaman kita, kita dapat melihat bahwa komponen AccountInfo kita merender dengan benar nilai yang diteruskan oleh induknya.

Seperti saat bekerja dengan direktif VueJS lainnya, kita dapat menggunakan v-bind untuk meneruskan props secara dinamis. Sebagai contoh, katakanlah kita ingin mengatur nama pengguna prop sama dengan variabel. Kita dapat melakukannya dengan menggunakan singkatan untuk direktif v-bind (atau singkatnya : . Kode akan terlihat sedikit seperti ini:

 <template> <div> <account-info :username="user.username" /> </div> </template> <script> import AccountInfo from "@/components/AccountInfo.vue"; export default { components: { AccountInfo }, data() { return { user: { username: 'matt' } } } } </script>

Ini berarti bahwa kami dapat mengubah data kami dan memiliki properti anak apa pun yang menggunakan nilai itu juga akan diperbarui.

Tip: Selalu Verifikasi Alat Peraga Anda

Jika Anda ingin menulis kode Vue yang lebih jelas, teknik penting adalah memverifikasi properti Anda. Singkatnya, ini berarti Anda perlu menentukan persyaratan untuk prop Anda (yaitu jenis, format, dan sebagainya). Jika salah satu dari persyaratan ini tidak terpenuhi (misalnya jika prop dilewatkan dengan tipe yang salah), Vue akan mencetak peringatan.

Katakanlah kita ingin prop nama pengguna kita hanya menerima Strings. Kita harus memodifikasi objek props kita agar terlihat seperti ini:

 export default { props: { username: String } }

Memverifikasi alat peraga sangat penting saat bekerja di aplikasi Vue skala besar atau saat merancang plugin. Ini membantu memastikan bahwa semua orang berada di halaman yang sama dan menggunakan alat peraga seperti yang dimaksudkan.

Untuk daftar lengkap verifikasi yang dapat kami sertakan pada alat peraga, saya pasti akan merekomendasikan untuk memeriksa dokumentasi resmi untuk tinjauan mendalam.

Tip: Ikuti Konvensi Penamaan Prop

Menurut panduan gaya VueJS, cara terbaik untuk menamai properti Anda adalah dengan menggunakan camelCase saat mendeklarasikannya dalam skrip dan kebab-case saat mereferensikannya dalam kode template.

Alasan di balik ini sebenarnya cukup sederhana. Dalam Javascript, camelCase adalah konvensi penamaan standar dan dalam HTML, ini adalah kebab-case.

Jadi, Vue merekomendasikan agar kita tetap berpegang pada norma setiap bahasa. Untungnya, Vue dapat secara otomatis mengonversi antara dua gaya sehingga tidak ada pengaturan tambahan untuk pengembang.

 // GOOD <account-info :my-username="user.username" /> props: { myUsername: String } // BAD <account-info :myUsername="user.username" /> props: { "my-username": String }

2. Memancarkan Acara Untuk Berbagi Data Dari Anak Ke Orang Tua

Sekarang setelah kita memiliki data yang melewati hierarki, mari kita meneruskannya dengan cara lain: dari komponen anak ke komponen induk. Kami tidak dapat menggunakan alat peraga, tetapi kami dapat menggunakan acara dan pendengar khusus.

Setiap instance Vue dapat memanggil metode .$emit(eventName) yang memicu sebuah event. Kemudian, kita dapat mendengarkan acara ini dengan cara yang sama seperti yang lain, menggunakan direktif v-on.

Membuat Acara Khusus

Mari kita membangun contoh profil pengguna kita dengan menambahkan tombol yang mengubah nama pengguna. Di dalam komponen anak kita ( AccountInfo.vue ), mari buat tombolnya.

Kemudian, ketika tombol ini diklik, kita akan mengeluarkan event bernama changeUsername .

 <template> <div id='account-info'> <button @click='changeUsername()'>Change Username</button> {{username}} </div> </template> <script> export default { props: { username: String }, methods: { changeUsername() { this.$emit('changeUsername') } } } </script>

Di dalam parent, kita menangani event ini dan mengubah variabel user.username . Seperti yang telah kita diskusikan sebelumnya, kita dapat mendengarkan acara menggunakan direktif v-on atau singkatnya "@".

 <template> <div> <account-info :username="user.username" @changeUsername="user.username = 'new name'"/> </div> </template>

Mari kita mencobanya. Anda akan melihat bahwa ketika Anda mengklik tombol, nama pengguna berubah menjadi "nama baru".

Tip: Acara Kustom Dapat Menerima Argumen

Kasus penggunaan yang paling umum untuk meneruskan argumen ke acara Anda adalah ketika Anda ingin komponen anak dapat menetapkan nilai tertentu untuk prop-nya. Anda tidak pernah ingin langsung mengedit nilai prop dari komponen itu sendiri.

Namun, untungnya kita bisa menggunakan argumen pass dengan event kustom kita untuk membuat nilai komponen induk berubah.

Katakanlah kita ingin memodifikasi event changeUsername sehingga kita bisa memberikan nilai.

Metode $emit mengambil parameter opsional kedua untuk argumen. Jadi yang kita lakukan hanyalah menambahkan nilai nama pengguna baru kita setelah nama acara kita.

 this.$emit('changeUsername', 'mattmaribojoc')

Kemudian, dalam komponen induk, kita dapat mengakses nilai-nilai ini sebaris dengan menggunakan variabel $event khusus, atau kita dapat menulis metode handler yang mengambil parameter.

 <account-info :username="user.username" @changeUsername="user.username = $event"/> OR <account-info :username="user.username" @changeUsername="changeUsername($event)"/> export default { ... methods: { changeUsername (username) { this.user.username = username; } } }

3. Menggunakan Vuex Untuk Membuat Status Bersama Tingkat Aplikasi

Oke — kita tahu cara berbagi data antara orang tua/anak, tapi bagaimana dengan komponen lainnya? Apakah kita harus membuat sistem hierarki yang sangat kompleks jika ingin melewatkan data?

Syukurlah tidak. Pustaka manajemen status Vuex yang luar biasa telah menyederhanakan kehidupan pengembang selama bertahun-tahun. Singkatnya, ini menciptakan penyimpanan data terpusat yang dapat diakses oleh semua komponen.

Dalam metode yang kami gunakan sebelumnya (props / emitting event), setiap komponen memiliki status datanya sendiri yang kemudian kami bagikan antar komponen. Namun, Vuex memungkinkan kami mengekstrak semua data yang dibagikan ke dalam satu status yang dapat diakses oleh setiap komponen dengan mudah. Status bersama ini disebut toko.

Mari kita mencobanya.

Karena Vuex terpisah dari kode inti Vue, pertama-tama kita harus menginstal dan mengimpornya ke dalam proyek kita. Pertama, kita harus menjalankan npm install vuex --save di dalam CLI proyek kita.

Kemudian, buat folder src/store dengan file index.js yang berisi kode berikut.

 // store/index.js import Vue from "vue"; import Vuex from "vuex"; Vue.use(Vuex); export default new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {} });

Untuk memasukkan ini ke dalam instance root Vue kami, kami harus mengimpor file store/index.js kami dan meneruskannya ke konstruktor Vue kami.

 // main.js import store from "./store"; new Vue({ store, ...

Mengakses Vue Store Inside Components

Karena kami menambahkan toko Vuex kami ke instance root Vue kami, itu akan disuntikkan ke semua anak root. Jika kita ingin mengakses store dari sebuah komponen, kita bisa melalui this.$store .

Sekarang, mari selami secara spesifik masing-masing dari empat bagian toko Vuec.

1. Negara

Status Vuex adalah objek yang berisi data level aplikasi. Semua instance Vue akan dapat mengakses data ini.

Untuk toko kita, mari buat objek pengguna yang menyimpan beberapa data profil pengguna lagi.

 export default new Vuex.Store({ state: { user: { username: 'matt', fullName: 'Matt Maribojoc' } }, getters: {}, mutations: {}, actions: {} });

Kami dapat mengakses data ini di dalam komponen instan apa pun seperti ini.

 mounted () { console.log(this.$store.state.user.username); },

2. Getter

Kami menggunakan getter Vuex untuk mengembalikan nilai data status yang dimodifikasi. Cara yang baik untuk memikirkan getter adalah memperlakukannya seperti properti yang dihitung. Misalnya, getter, seperti properti yang dihitung, menyimpan hasil mereka dalam cache dan hanya mengevaluasi ulang saat ketergantungan diubah.

Membangun ke toko kami sebelumnya, katakanlah kami ingin membuat metode yang mengembalikan nama depan pengguna berdasarkan atribut nama lengkap.

 getters: { firstName: state => { return state.user.fullName.split(' ')[0] } }

Properti pengambil Vuex tersedia untuk komponen pada objek store.getters .

 mounted () { console.log(this.$store.getters.firstName); }

Tip: Ketahui Argumen Pengambil Default

Secara default, getter Vuex menerima dua argumen.

  1. state — objek state untuk aplikasi kita;
  2. getter — objek store.getters, artinya kita dapat memanggil getter lain di toko kita.

Setiap pengambil yang Anda nyatakan akan membutuhkan argumen status pertama. Dan tergantung pada bagaimana Anda mendesain kode Anda, getter Anda dapat saling mereferensikan menggunakan argumen 'getter' kedua.

Mari kita buat pengambil nama belakang yang hanya menghapus nilai nama depan kita dari properti status nama lengkap kita. Contoh ini akan membutuhkan objek state dan getter.

 lastName (state, getters) { return state.user.fullName.replace(getters.firstName, ''); }

Tip: Berikan Argumen Kustom ke Vuex Getter

Fitur getter keren lainnya adalah kita bisa meneruskan argumen kustom dengan membuat getter kita mengembalikan sebuah metode.

 prefixedName: (state, getters) => (prefix) => { return prefix + getters.lastName; } // in our component console.log(this.$store.getters.prefixedName("Mr."));

3. Mutasi

Mutasi adalah satu- satunya cara untuk mengubah nilai objek keadaan dengan benar. Detail penting yang perlu diperhatikan adalah bahwa mutasi harus sinkron .

Seperti getter, mutasi selalu menerima properti status Vuex sebagai argumen pertama mereka. Mereka juga menerima argumen khusus — disebut payload — sebagai argumen kedua.

Misalnya, mari kita membuat mutasi untuk mengubah nama pengguna menjadi nilai tertentu.

 mutations: { changeName (state, payload) { state.user.fullName = payload } },

Kemudian, kita dapat memanggil metode ini dari komponen kita menggunakan metode store.commit , dengan payload kita sebagai argumen kedua.

 this.$store.commit("changeName", "New Name");

Lebih sering daripada tidak, Anda ingin muatan Anda menjadi objek. Ini tidak hanya berarti bahwa Anda dapat meneruskan beberapa argumen ke mutasi, tetapi juga, itu membuat kode Anda lebih mudah dibaca karena nama properti di objek Anda.

 changeName (state, payload) { state.user.fullName = payload.newName }

Ada dua cara berbeda untuk memanggil mutasi dengan muatan.

  1. Anda dapat memiliki tipe mutasi sebagai argumen pertama dan payload sebagai argumen kedua.
  2. Anda dapat mendeklarasikan melewati satu objek, dengan satu properti untuk tipe dan satu lagi untuk payload.
 this.$store.commit("changeName", { newName: "New Name 1", }); // or this.$store.commit({ type: "changeName", newName: "New Name 2" });

Tidak ada perbedaan nyata antara cara keduanya bekerja, jadi itu sepenuhnya tergantung pada preferensi pribadi. Ingatlah bahwa yang terbaik adalah selalu konsisten di seluruh proyek Anda, jadi mana pun yang Anda pilih, tetaplah melakukannya!

4. Tindakan

Di Vuex, tindakan cukup mirip dengan mutasi karena kami menggunakannya untuk mengubah keadaan. Namun, tindakan tidak mengubah nilai itu sendiri. Sebaliknya, tindakan melakukan mutasi.

Juga, sementara mutasi Vuex harus sinkron, tindakan tidak. Menggunakan tindakan, kita dapat memanggil mutasi setelah panggilan API, misalnya.

Sementara sebagian besar penangan Vuex yang kita lihat menerima status sebagai parameter utamanya, tindakan menerima objek konteks. Objek konteks ini memungkinkan kita untuk mengakses properti di toko Vuex kita (misalnya status, komit, getter).

Berikut adalah contoh tindakan Vuex yang menunggu dua detik dan kemudian melakukan mutasi changeName .

 actions: { changeName (context, payload) { setTimeout(() => { context.commit("changeName", payload); }, 2000); } }

Di dalam komponen kami, kami menggunakan metode store.dispatch untuk menjalankan fungsi kami. Kami menyampaikan argumen seperti yang kami lakukan dengan mutasi. Kami mendeklarasikan tipe dan kami meneruskan argumen khusus apa pun dalam argumen kedua.

 this.$store.dispatch("changeName", { newName: "New Name from Action" });

Membungkus

Sekarang, Anda harus mengetahui tiga cara berbeda untuk berbagi data di seluruh komponen di VueJS: props, custom event, dan Vuex store.

Saya harap tutorial ini membantu memberi Anda lebih banyak wawasan tentang beberapa metode dan praktik terbaik Vue yang berbeda. Beri tahu saya bagaimana Anda menerapkannya ke dalam proyek Anda!

Bacaan lebih lanjut

Jika Anda tertarik untuk masuk lebih dalam ke sisi teknis/kemampuan setiap teknik, berikut adalah beberapa tempat yang bagus untuk memulai.

  • Situs web Panduan Resmi Vuex
  • Dokumen VueJS untuk Alat Peraga dan Acara Khusus
  • “WTF Apakah Vuex? Panduan Pemula Untuk Penyimpanan Data Aplikasi Vue,” Anthony Gore, Pengembang Vue.js