Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Vue
Code

Cara Membangun Kompleks, Skala-Besar Aplikasi Vue.js Dengan Vuex

by
Difficulty:AdvancedLength:LongLanguages:

Indonesian (Bahasa Indonesia) translation by Ilham Saputra (you can also view the original English article)

Sangat mudah untuk mempelajari dan menggunakan Vue.js bahwa setiap orang dapat membangun aplikasi sederhana dengan framework itu. Bahkan pemula, dengan bantuan dokumentasi Vue, dapat melakukan pekerjaan itu. Namun, ketika kompleksitas mulai bekerja, hal-hal menjadi sedikit lebih serius. Yang benar adalah bahwa beberapa komponen yang sangat bersarang dengan keadaan bersama dapat dengan cepat mengubah aplikasi Anda menjadi kekacauan yang tidak terawat.

Masalah utama dalam aplikasi kompleks adalah bagaimana mengelola keadaan antara komponen tanpa menulis kode spaghetti atau menghasilkan efek samping. Dalam tutorial ini Anda akan belajar bagaimana menyelesaikan masalah itu dengan menggunakan Vuex: perpustakaan manajemen negara untuk membangun aplikasi Vue.js yang kompleks.

Apa itu Vuex?

Vuex adalah pustaka manajemen negara yang secara khusus dicari untuk membangun aplikasi Vue.js yang kompleks dan berskala besar. Ini menggunakan global, toko terpusat untuk semua komponen dalam aplikasi, mengambil keuntungan dari sistem reaktivitasnya untuk pembaruan instan.

Vuex store dirancang sedemikian rupa sehingga tidak mungkin mengubah negaranya dari komponen apa pun. Ini memastikan bahwa negara hanya dapat bermutasi dengan cara yang dapat diprediksi. Dengan demikian toko Anda menjadi satu sumber kebenaran: setiap elemen data hanya disimpan sekali dan hanya dapat dibaca untuk mencegah komponen aplikasi merusak keadaan yang diakses oleh komponen lain.

Mengapa Anda Perlu Vuex?

Anda mungkin bertanya: Mengapa saya perlu Vuex di tempat pertama? Tidak bisakah saya memasukkan status bersama dalam file JavaScript biasa dan mengimpornya ke aplikasi Vue.js saya?

Tentu saja, Anda dapat, tetapi dibandingkan dengan objek global biasa, Vuex store memiliki beberapa keuntungan dan manfaat yang signifikan:

  • Vuex store bersifat reaktif. Setelah komponen mengambil status dari itu, mereka akan secara reaktif memperbarui pandangan mereka setiap kali keadaan berubah.
  • Komponen tidak dapat secara langsung mengubah keadaan store. Satu-satunya cara untuk mengubah status store adalah dengan secara eksplisit melakukan mutasi. Ini memastikan setiap perubahan status meninggalkan catatan yang dapat dilacak, yang membuat aplikasi lebih mudah untuk didebug dan diuji.
  • Anda dapat dengan mudah men-debug aplikasi Anda berkat integrasi Vuex dengan ekstensi Vue's DevTools.
  • Vuex store memberi Anda pandangan mata burung tentang bagaimana segala sesuatu terhubung dan terpengaruh dalam aplikasi Anda.
  • Lebih mudah untuk mempertahankan dan menyinkronkan status antara beberapa komponen, bahkan jika hierarki komponen berubah.
  • Vuex membuat komunikasi lintas komponen langsung menjadi mungkin.
  • Jika sebuah komponen dihancurkan, negara di Vuex store akan tetap utuh.

Memulai dengan Vuex

Sebelum memulai, saya ingin membuat beberapa hal jelas.

Pertama, untuk mengikuti tutorial ini, Anda harus memiliki pemahaman yang baik tentang Vue.js dan sistem komponennya, atau setidaknya pengalaman minimal dengan framework.

Selain itu, tujuan dari tutorial ini bukan untuk menunjukkan kepada Anda bagaimana membangun aplikasi kompleks yang sebenarnya; tujuannya adalah untuk lebih memfokuskan perhatian Anda pada konsep Vuex dan bagaimana Anda dapat menggunakannya untuk membangun aplikasi yang kompleks. Untuk alasan itu, saya akan menggunakan contoh yang sangat jelas dan sederhana, tanpa kode yang berlebihan. Setelah Anda sepenuhnya memahami konsep Vuex, Anda akan dapat menerapkannya pada tingkat kerumitan apa pun.

Akhirnya, saya akan menggunakan sintaks ES2015. Jika Anda tidak terbiasa dengannya, Anda dapat mempelajarinya di sini.

Dan sekarang, mari kita mulai!

Menyiapkan sebuah Proyek Vuex

Langkah pertama untuk memulai dengan Vuex adalah menginstal Vue.js dan Vuex di komputer Anda. Ada beberapa cara untuk melakukannya, tetapi kami akan menggunakan yang paling mudah. Cukup buat file HTML dan tambahkan tautan CDN yang diperlukan:

Saya menggunakan beberapa CSS untuk membuat komponen terlihat lebih bagus, tetapi Anda tidak perlu khawatir tentang kode CSS itu. Itu hanya membantu Anda mendapatkan gagasan visual tentang apa yang sedang terjadi. Cukup salin dan tempelkan yang berikut di dalam tag <head>:

Sekarang, mari buat beberapa komponen untuk dikerjakan. Di dalam tag <script>, tepat di atas tag penutup </body>, masukkan kode Vue berikut:

Di sini, kami memiliki contoh Vue, komponen induk, dan dua komponen anak. Setiap komponen memiliki judul "Score:" di mana kami akan menampilkan status aplikasi.

Hal terakhir yang perlu Anda lakukan adalah untuk menempatkan pembungkus <div> dengan id="app" kanan setelah pembukaan <body>, dan kemudian menempatkan komponen induk dalam:

Pekerjaan persiapan sekarang sudah selesai, dan kami siap untuk melanjutkan.

Menjelajahi Vuex

Manajemen Status

Dalam kehidupan nyata, kita berurusan dengan kompleksitas dengan menggunakan strategi untuk mengatur dan menyusun konten yang ingin kita gunakan. Kami mengelompokkan hal-hal terkait dalam berbagai bagian, kategori, dll. Ini seperti perpustakaan buku, di mana buku-buku dikategorikan dan diletakkan di bagian yang berbeda sehingga kita dapat dengan mudah menemukan apa yang kita cari. Vuex mengatur data aplikasi dan logika yang terkait dengan negara dalam empat kelompok atau kategori: state, getters, mutations, and actions.

State dan mutations adalah basis untuk setiap Vuex store:

  • state adalah objek yang menyimpan status data aplikasi.
  • mutations juga merupakan objek yang mengandung metode yang mempengaruhi state.

Getters dan actions seperti proyeksi logis dari state dan mutations:

  • getters berisi metode yang digunakan untuk abstrak akses ke state, dan untuk melakukan beberapa pekerjaan preprocessing, jika diperlukan (data menghitung, penyaringan, dll).
  • actions adalah metode yang digunakan untuk memicu mutations dan mengeksekusi kode asinkron.

Mari kita menjelajahi diagram berikut untuk membuat hal-hal yang sedikit lebih jelas:

Vuex State Management Workflow Diagram

Di sebelah kiri, kami memiliki contoh toko Vuex, yang akan kami buat nanti di tutorial ini. Di sisi kanan, kami memiliki diagram alur kerja Vuex, yang menunjukkan bagaimana berbagai elemen Vuex bekerja bersama dan berkomunikasi satu sama lain.

Untuk mengubah keadaan, komponen Vue tertentu harus melakukan mutasi (misalnya. this.$Store.commit('increment', 3)), dan kemudian, mutasi tersebut mengubah status (score menjadi 3). Setelah itu, getter diperbarui secara otomatis berkat sistem reaktif Vue, dan mereka membuat pembaruan dalam tampilan komponen (dengan this.$Store.getters.score).

Mutasi tidak dapat mengeksekusi kode asinkron, karena ini akan membuat tidak mungkin untuk merekam dan melacak perubahan dalam alat debug seperti Vue DevTools. Untuk menggunakan logika asynchronous, Anda harus memasukkannya ke dalam aksi. Dalam hal ini, komponen pertama akan mengirim aksi (this.$Store.dispatch('incrementScore', 3000)) di mana kode asynchronous dijalankan, dan kemudian aksi tersebut akan melakukan mutasi, yang akan memutasi status.

Buat Kerangka Vuex Store

Sekarang setelah kami menjelajahi cara kerja Vuex, mari buat kerangka untuk Vuex store kami. Masukkan kode berikut di atas pendaftaran komponen ChildB:

Untuk menyediakan akses global ke Vuex store dari setiap komponen, kita perlu menambahkan properti store dalam contoh Vue:

Sekarang, kita dapat mengakses toko dari setiap komponen dengan variabel this.$store.

Sejauh ini, jika Anda membuka proyek dengan CodePen di browser, Anda akan melihat hasil berikut.

App Skeleton

Properti State

Objek state berisi semua data yang dibagi dalam aplikasi Anda. Tentu saja, jika diperlukan, setiap komponen dapat memiliki status privasinya sendiri juga.

Bayangkan Anda ingin membuat aplikasi game, dan Anda memerlukan variabel untuk menyimpan skor game. Jadi Anda memasukkannya ke objek status:

Sekarang, Anda dapat mengakses status skor secara langsung. Mari kita kembali ke komponen dan menggunakan kembali data dari toko. Agar dapat menggunakan kembali data reaktif dari status toko, Anda harus menggunakan properti yang dihitung. Jadi mari kita buat properti score() yang dihitung dalam komponen induk:

Dalam template komponen induk, masukkan ekspresi {{ score }}:

Dan sekarang, lakukan hal yang sama untuk dua komponen child.

Vuex sangat pintar sehingga akan melakukan semua pekerjaan bagi kita untuk secara aktif memperbarui properti score setiap kali negara berubah. Cobalah untuk mengubah nilai skor dan lihat bagaimana hasil pembaruan di ketiga komponen.

Membuat Getters

Tentu saja, Anda dapat menggunakan kembali this.$Store.state kata kunci di dalam komponen, seperti yang Anda lihat di atas. Tapi bayangkan skenario berikut:

  1. Dalam aplikasi skala besar, dimana beberapa komponen mengakses negara toko dengan menggunakan ini. $store.state.score, Anda memutuskan untuk mengubah nama score. Ini berarti bahwa Anda harus mengubah nama variabel dalam setiap komponen yang menggunakannya!
  2. Anda ingin menggunakan nilai terhitung dari bagian status. Sebagai contoh, katakanlah Anda ingin memberikan bonus 10 poin kepada pemain saat skor mencapai 100 poin. Jadi, ketika skor mencapai 100 poin, bonus 10 poin ditambahkan. Ini berarti setiap komponen harus berisi fungsi yang menggunakan kembali skor dan menambahkannya dengan 10. Anda akan memiliki kode berulang di setiap komponen, yang tidak bagus sama sekali!

Untungnya, Vuex menawarkan solusi yang berfungsi untuk menangani situasi semacam itu. Bayangkan pengambil terpusat yang mengakses keadaan toko dan menyediakan fungsi pengambil untuk masing-masing item status. Jika diperlukan, pengambil ini dapat menerapkan beberapa perhitungan ke item status. Dan jika Anda perlu mengubah nama beberapa properti status, Anda hanya mengubahnya di satu tempat, di pengambil ini.

Mari kita membuat score() getter:

Seorang pengambil menerima state sebagai argumen pertama, dan kemudian menggunakannya untuk mengakses properti status.

Catatan: Getters juga menerima getters sebagai argumen kedua. Anda dapat menggunakannya untuk mengakses getter lain di toko.

Di semua komponen, ubahlah score() properti yang dihitung untuk menggunakan score() pengambil alih, bukan skor status langsung.

Sekarang, jika Anda memutuskan untuk mengubah score menjadi result, Anda perlu memperbaruinya hanya di satu tempat: di score() pengambil. Coba di CodePen ini!

Membuat Mutasi

Mutasi adalah satu-satunya cara yang diizinkan untuk mengubah negara. Memicu perubahan berarti melakukan mutasi dalam metode komponen.

Mutasi adalah cukup banyak fungsi event handler yang didefinisikan oleh nama. Fungsi pengendali mutasi menerima state sebagai argumen pertama. Anda dapat mengirimkan argumen tambahan kedua juga, yang disebut payload untuk mutasi.

Mari kita buat mutasi increment():

Mutasi tidak bisa disebut secara langsung! Untuk melakukan mutasi, Anda harus memanggil metode commit() dengan nama mutasi terkait dan kemungkinan parameter tambahan. Mungkin hanya satu, seperti step dalam kasus kami, atau mungkin ada beberapa yang dibungkus dalam suatu objek.

Mari kita gunakan mutasi increment() dalam dua komponen anak dengan membuat metode bernama changeScore():

Kami melakukan mutasi alih-alih mengubah this.$Store.state.score secara langsung, karena kami ingin secara eksplisit melacak perubahan yang dibuat oleh mutasi. Dengan cara ini, kami membuat logika aplikasi kami lebih transparan, dapat dilacak, dan mudah untuk dibicarakan. Selain itu, memungkinkan untuk mengimplementasikan alat, seperti Vue DevTools atau Vuetron, yang dapat mencatat semua mutasi, mengambil snapshot status, dan melakukan debug perjalanan waktu.

Sekarang, mari kita gunakan metode changeScore(). Di setiap template dari dua komponen anak, buat tombol dan tambahkan listener kejadian untuk itu:

Ketika Anda mengklik tombol, negara akan bertambah 3, dan perubahan akan tercermin dalam semua komponen. Sekarang kami telah berhasil mencapai komunikasi lintas komponen langsung, yang tidak mungkin dengan mekanisme "props down, events up" Vue.js built-in. Lihat di contoh CodePen kami.

Membuat Aksi

Suatu aksi hanyalah sebuah fungsi yang melakukan mutasi. Ini mengubah negara secara tidak langsung, yang memungkinkan untuk pelaksanaan operasi asynchronous.

Mari kita buat aksi incrementScore():

Tindakan mendapatkan context sebagai parameter pertama, yang berisi semua metode dan properti dari toko. Biasanya, kami hanya mengekstrak bagian-bagian yang kami butuhkan dengan menggunakan argumentasi destructuring ES2015. Metode commit adalah salah satu yang sangat kami butuhkan. Tindakan juga mendapatkan argumen muatan kedua, seperti halnya mutasi.

Dalam komponen ChildB, ubah metode changeScore():

Untuk memanggil suatu tindakan, kami menggunakan metode dispatch() dengan nama tindakan yang sesuai dan parameter tambahan, seperti halnya mutasi.

Sekarang, tombol Change Score dari komponen ChildA akan menaikkan skor dengan 3. Tombol yang sama dari komponen ChildB akan melakukan hal yang sama, tetapi setelah penundaan 3 detik. Pada kasus pertama, kami mengeksekusi kode sinkron dan kami menggunakan mutasi, tetapi dalam kasus kedua kami mengeksekusi kode asinkron, dan kami perlu menggunakan tindakan sebagai gantinya. Lihat bagaimana semuanya berfungsi dalam contoh CodePen kami.

Pemandu Pemetaan Vuex

Vuex menawarkan beberapa pembantu yang berguna yang dapat menyederhanakan proses pembuatan negara, pengambil, mutasi, dan tindakan. Alih-alih menulis fungsi-fungsi itu secara manual, kita dapat memberi tahu Vuex untuk membuatnya untuk kita. Mari kita lihat cara kerjanya.

Alih-alih menulis score() dihitung properti seperti ini:

Kami hanya menggunakan helper mapState() seperti ini:

Dan properti score() dibuat secara otomatis untuk kami.

Hal yang sama berlaku untuk getter, mutasi, dan aksi.

Untuk membuat score() pengambil, kami menggunakan helper mapGetters():

Untuk membuat metode changeScore(), kami menggunakan helper mapMutations() seperti ini:

Ketika digunakan untuk mutasi dan aksi dengan argumen payload, kita harus meneruskan argumen itu dalam template tempat kita mendefinisikan pengendali event:

Jika kita ingin changeScore() menggunakan tindakan, bukan mutasi, kami menggunakan mapActions() seperti ini:

Sekali lagi, kita harus menentukan penundaan dalam pengendali event:

Catatan: Semua petugas pemetaan mengembalikan objek. Jadi, jika kita ingin menggunakannya dalam kombinasi dengan properti atau metode komputasi lokal lainnya, kita perlu menggabungkannya ke dalam satu objek. Untungnya, dengan operator penyebaran objek (...), kita dapat melakukannya tanpa menggunakan utilitas apa pun.

Di dalam CodePen kami, Anda dapat melihat contoh bagaimana semua pembantu pemetaan digunakan dalam praktik.

Membuat Toko Lebih Modular

Tampaknya masalah dengan kompleksitas secara terus-menerus menghalangi jalan kita. Kami memecahkannya sebelumnya dengan membuat toko Vuex, di mana kami membuat manajemen negara dan komunikasi komponen menjadi mudah. Di toko itu, kita memiliki segalanya di satu tempat, mudah dimanipulasi dan mudah ditebak.

Namun, seiring dengan berkembangnya aplikasi kami, file toko yang mudah dikelola ini menjadi semakin besar dan, akibatnya, semakin sulit dipelihara. Sekali lagi, kami memerlukan beberapa strategi dan teknik untuk meningkatkan struktur aplikasi dengan mengembalikannya ke bentuknya yang mudah dirawat. Pada bagian ini, kita akan membahas beberapa teknik yang dapat membantu kita dalam hal ini.

Menggunakan Modul Vuex

Vuex memungkinkan kita membagi objek penyimpanan menjadi modul terpisah. Setiap modul dapat berisi statusnya sendiri, mutasi, tindakan, getter, dan modul bersarang lainnya. Setelah kami membuat modul yang diperlukan, kami mendaftarkannya di toko.

Mari kita melihatnya dalam aksi:

Dalam contoh di atas, kami membuat dua modul, satu untuk setiap komponen anak. Modul-modulnya hanyalah objek biasa, yang kita daftarkan sebagai scoreBoard dan resultBoard dalam objek modules di dalam toko. Kode untuk childA sama dengan kode di contoh sebelumnya. Dalam kode untuk childB, kami menambahkan beberapa perubahan dalam nilai dan nama.

Sekarang mari kita tweak komponen ChildB untuk mencerminkan perubahan dalam modul resultBoard.

Dalam komponen ChildA, satu-satunya hal yang perlu kita modifikasi adalah metode changeScore():

Seperti yang Anda lihat, memisahkan toko ke dalam modul membuatnya jauh lebih ringan dan mudah dipelihara, sambil tetap menjaga fungsionalitasnya yang luar biasa. Lihat CodePen yang diperbarui untuk melihatnya beraksi.

Modul Namespaced

Jika Anda ingin atau perlu menggunakan satu dan nama yang sama untuk properti atau metode tertentu dalam modul Anda, maka Anda harus mempertimbangkan ruang nama. Jika tidak, Anda dapat mengamati beberapa efek samping yang aneh, seperti mengeksekusi semua tindakan dengan nama yang sama, atau mendapatkan nilai-nilai status yang salah.

Untuk menamai modul Vuex, Anda hanya mengatur properti namespaced ke true.

Dalam contoh di atas, kami membuat nama properti dan metode yang sama untuk dua modul. Dan sekarang kita bisa menggunakan properti atau metode yang diawali dengan nama modul. Sebagai contoh, jika kita ingin menggunakan score() pengambil dari modul resultBoard, kita ketik seperti ini: resultBoard/score. Jika kita menginginkan score() pengambil dari modul scoreBoard, maka kita ketik seperti ini: scoreBoard/score.

Mari sekarang memodifikasi komponen kami untuk mencerminkan perubahan yang kami buat.

Seperti yang Anda lihat dalam contoh CodePen kami, sekarang kami dapat menggunakan metode atau properti yang kami inginkan dan mendapatkan hasil yang kami harapkan.

Memisahkan Vuex Store menjadi File Terpisah

Pada bagian sebelumnya, kami meningkatkan struktur aplikasi sampai batas tertentu dengan memisahkan toko ke dalam modul. Kami membuat toko lebih bersih dan lebih teratur, tetapi masih semua kode toko dan modulnya terletak pada file besar yang sama.

Jadi langkah logis selanjutnya adalah membagi toko Vuex menjadi file terpisah. Idenya adalah memiliki file individu untuk toko itu sendiri dan satu untuk masing-masing objeknya, termasuk modul. Ini berarti memiliki file terpisah untuk negara, getter, mutasi, tindakan, dan untuk setiap modul individual (store.js, state.js, getters.js, dll.) Anda dapat melihat contoh struktur ini di akhir berikutnya bagian.

Menggunakan Vue Single File Components

Kami telah membuat toko Vuex sebagai modular yang kami bisa. Hal berikutnya yang bisa kita lakukan adalah menerapkan strategi yang sama ke komponen Vue.js juga. Kita dapat menempatkan setiap komponen dalam satu file mandiri dengan ekstensi .vue. Untuk mempelajari cara kerjanya, Anda dapat mengunjungi halaman dokumen Vue Single File Components.

Jadi, dalam kasus kami, kami akan memiliki tiga file: Parent.vue, ChildA.vue, dan ChildB.vue.

Akhirnya, jika kita menggabungkan ketiga teknik, kita akan berakhir dengan struktur berikut atau serupa:

Dalam tutorial repo GitHub kami, Anda dapat melihat proyek selesai dengan struktur di atas.

Ikhtisar

Mari kita rangkum beberapa poin utama yang perlu Anda ingat tentang Vuex:

Vuex adalah perpustakaan manajemen negara yang membantu kita membangun aplikasi skala besar yang kompleks. Ini menggunakan toko global terpusat untuk semua komponen dalam aplikasi. Untuk mengaburkan negara, kami menggunakan getter. Getters cukup mirip dengan properti yang dihitung dan merupakan solusi ideal ketika kita perlu memfilter atau menghitung sesuatu pada waktu proses.

Toko Vuex bersifat reaktif, dan komponen tidak dapat langsung memutasikan status toko. Satu-satunya cara untuk mengubah keadaan adalah dengan melakukan mutasi, yang merupakan transaksi sinkron. Setiap mutasi harus melakukan hanya satu tindakan, harus sesederhana mungkin, dan hanya bertanggung jawab untuk memperbarui sepotong status.

Logika asynchronous harus dienkapsulasi dalam tindakan. Setiap tindakan dapat melakukan satu atau lebih mutasi, dan satu mutasi dapat dilakukan oleh lebih dari satu tindakan. Perbuatan bisa rumit, tetapi mereka tidak pernah mengubah status secara langsung.

Akhirnya, modularitas adalah kunci untuk pemeliharaan. Untuk menghadapi kompleksitas dan membuat kode kita modular, kami menggunakan prinsip "membagi dan menaklukkan" dan teknik pemecahan kode.

Kesimpulan

Itu dia! Anda sudah mengetahui konsep utama di balik Vuex, dan Anda siap untuk mulai menerapkannya dalam praktik.

Demi keringkasan dan kesederhanaan, saya sengaja menghilangkan beberapa detail dan fitur Vuex, jadi Anda harus membaca dokumentasi Vuex lengkap untuk mempelajari segala sesuatu tentang Vuex dan fitur-fiturnya.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.