Menguasai Vuex - Dari Nol ke Pahlawan

Halo, Habr! Saya mempersembahkan untuk Anda terjemahan dari artikel “Mastering Vuex - Zero to Hero” oleh Sanath Kumar.


Dokumentasi resmi Vuex mendefinisikannya sebagai pola + perpustakaan manajemen negara untuk aplikasi Vue.js. Tapi apa artinya itu? Apa itu pola manajemen negara?


Bayangkan Anda sedang mengerjakan aplikasi web besar dengan ratusan rute dan komponen. Bukankah lebih mudah jika kita bisa menyimpan semua data yang kita perlukan dalam aplikasi dalam satu penyimpanan terpusat?



Setiap komponen atau rute dalam aplikasi kita akan meminta data dari negara Vuex dan mentransfer data yang diubah kembali ke keadaan.


Intinya, keadaan Vuex dapat dilihat sebagai satu-satunya sumber kebenaran untuk seluruh aplikasi.


Data disimpan di dalam negara sebagai objek JSON. Sebagai contoh:


state: { name: "John Doe", age: "28" } 

Tetapi bagaimana komponen dan rute kita dapat mengakses data yang disimpan di negara kita? Untuk melakukan ini, kita perlu mendefinisikan getter di dalam repositori Vuex kita yang akan mengembalikan data dari repositori ke komponen kita. Mari kita lihat seperti apa seorang pengambil sederhana, yang mendapatkan nama dari repositori kami:


 getters: { NAME: state => { return state.name; }, } 

Perhatikan bahwa nama pengambil dalam huruf kapital. Ini hanya rekomendasi gaya kode. Tidak perlu mengikutinya jika Anda tidak menyukainya.


Sekarang kita telah menetapkan pengambil untuk nama, sangat mudah untuk mendapatkan nilai nama di dalam komponen kita. Kode di bawah ini memungkinkan Anda untuk melakukan ini.


 let name = this.$store.getters.NAME; 

Kami menemukan cara untuk mendapatkan data dari penyimpanan. Sekarang mari kita lihat bagaimana kita dapat mengatur data di repositori. Kami akan menentukan setter, kan? Selain itu, setter Vuex dinamai sedikit berbeda. Kami mendefinisikan Mutasi untuk mengatur data ke status Vuex kami.


 mutations: { SET_NAME: (state, payload) => { state.name = payload; }, } 

Apa lagi payload? Payload adalah data yang dikirim ke mutasi kami dari komponen yang membuat mutasi. Bagaimana kita bisa melakukan ini? Sangat sederhana:


 this.$store.commit('SET_NAME', your_name); 

Sepotong kode ini akan mengubah status aplikasi dan menetapkan nilai apa pun yang ditetapkan pada namaAnda untuk properti nama di dalam repositori kami.


MUTASI SINKRON


Bayangkan kita memiliki daftar nama yang disimpan dalam database di server jauh. Server memberi kami titik akhir yang mengembalikan array nama yang dapat digunakan di Vue.js. Tentu saja, kita dapat menggunakan Axios untuk menanyakan titik akhir dan mendapatkan data.


 let {data} = await Axios.get('https://myapiendpoint.com/api/names'); 

Setelah itu, kita bisa meneruskan array yang dikembalikan ke keadaan Vuex store kita menggunakan mutasi. Mudah kan? Tapi tidak juga. Mutasi bersifat sinkron, dan kami tidak dapat menjalankan operasi asinkron, seperti panggilan API, di dalam mutasi.


Apa yang harus kita lakukan? Buat Tindakan .


Tindakan itu seperti mutasi, tetapi alih-alih mengubah keadaan secara langsung, mereka membuat mutasi. Kedengarannya membingungkan? Mari kita lihat pengumuman aksi.


 actions: { SET_NAME: (context, payload) { context.commit('SET_NAME', payload); }, } 

Kami mendefinisikan tindakan yang disebut SET_NAME yang menggunakan konteks dan muatan sebagai parameter. Tindakan ini melakukan mutasi SET_NAME, yang dibuat sebelumnya, dengan data diteruskan ke sana, yaitu namaAnda .


Sekarang, alih-alih meminta mutasi secara langsung, komponen kami memicu tindakan SET_NAME dengan nama baru sebagai data sebagai berikut:


 this.$store.dispatch('SET_NAME', your_name); 

Kemudian tindakan memulai mutasi dengan data yang diteruskan ke sana, yaitu nama_Anda .



Tapi mengapa?


Anda mungkin bertanya-tanya mengapa deklarasi tindakan diperlukan jika kita dapat memulai mutasi dengan nilai baru langsung dari komponen kami. Seperti disebutkan di atas, mutasi bersifat sinkron, tetapi tidak ada tindakan.


Dalam contoh di atas, kasus dipertimbangkan ketika Anda perlu memperbarui nilai nama, tetapi tidak hanya dalam keadaannya, tetapi juga dalam database yang berjalan di server jauh. Saya yakin ini adalah bagaimana Anda berniat untuk menggunakan Vuex dalam proyek nyata dalam 99% kasus. Lihatlah potongan kode berikut:


 mutations: { SET_NAME: (state, name) => { state.name = name; }, }, actions: { SET_NAME: async (context, name) => { let {data} = await Axios.post('http://myapiendpoint.com/api/name', {name: name}); if (data.status == 200) { context.commit('SET_NAME', name); } }, } 

Kode itu sendiri sudah jelas. Kami menggunakan Axios untuk mengirim nama ke titik akhir. Jika permintaan POST berhasil, dan nilai nama bidang berhasil diubah di server, kami memulai mutasi SET_ NAME untuk memperbarui nilai nama di dalam negara bagian kami.


MENGAMBIL PRAKTEK TIDAK PERNAH MEMULAI MUTASI LANGSUNG. UNTUK INI SELALU MENGGUNAKAN TINDAKAN.



Mengkonfigurasi Penyimpanan Vuex di Vue.JS


Mari selami lebih dalam dan temukan bagaimana kita bisa mengimplementasikan Vuex dalam aplikasi nyata.


Langkah 1. Instal Vuex


 npm install --save vuex 

Langkah 2. Membuat repositori Vuex


  1. Buat direktori toko di root aplikasi kita.
  2. Buat file index.js di direktori ini dan gunakan kode di bawah ini untuk membuat repositori baru.

 import Vue from 'vue'; import Vuex from 'vuex'; Vue.use(Vuex); export const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, }); 

Langkah 3. Menambahkan Penyimpanan Vuex ke Aplikasi Vue.JS


1. Impor repositori ke file main.js:


 import {store} from './store'; 

2. Tambahkan penyimpanan ke instance Vue, seperti yang ditunjukkan di bawah ini:


 new Vue({ el: '#app', store, router, render: h => h(App), }); 

Sekarang kita dapat menambahkan variabel status, getter, mutasi, dan tindakan ke repositori Vuex kami.



Contoh


Lihatlah repositori Vuex dari aplikasi daftar tugas yang sederhana. “Bukan hanya daftar pekerjaan yang harus dilakukan !!!”. Hah? Jangan khawatir. Di akhir artikel ini, Anda akan belajar cara menggunakan kekuatan penuh dan kekuatan Vuex.


 import Vue from 'vue'; import Vuex from 'vuex'; import Axios from 'axios'; Vue.use(Vuex); export const store = new Vuex.Store({ state: { todos: null, }, getters: { TODOS: state => { return state.todos; }, }, mutations: { SET_TODO: (state, payload) => { state.todos = payload; }, ADD_TODO: (state, payload) => { state.todos.push(payload); }, }, actions: { GET_TODO: async (context, payload) => { let {data} = await Axios.get('http://yourwebsite.com/api/todo'); context.commit('SET_TODO', data); }, SAVE_TODO: async (context, payload) => { let {data} = await Axios.post('http://yourwebsite.com/api/todo'); context.commit('ADD_TODO', payload); }, }, }); 


Tambahkan item baru ke daftar agenda


Di dalam komponen Anda, mulailah tindakan SAVE_TODO dengan mengirimkan item tugas yang harus dilakukan kepadanya, seperti yang ditunjukkan dalam cuplikan kode di bawah ini.


 let item = 'Get groceries'; this.$store.dispatch('SAVE_TODO', item); 

Tindakan SAVE_TODO membuat permintaan POST ke titik akhir, dan kemudian memulai mutasi ADD_TODO , yang menambahkan item agenda ke variabel status todos .



Aktivitas yang harus dilakukan


Di dalam blok mount () komponen Anda, awali aksi GET_TODO kedua, yang menerima semua item yang harus dilakukan dari titik akhir dan menyimpannya dalam variabel status todos , memulai mutasi SET_TODO:


 mounted() { this.$store.dispatch('GET_TODO'); } 


Akses item yang harus dilakukan di dalam suatu komponen


Untuk mengakses elemen todos di dalam komponen, buat properti yang dihitung:


 computed: { todoList() { return this.$store.getters.TODOS; }, } 

Di dalam komponen, Anda dapat mengakses properti yang dihitung:


 <div class="todo-item" v-for="item in todoList"></div> 


Menggunakan Metode mapGetters


Bahkan ada cara yang lebih mudah untuk mengakses item-item yang harus dilakukan dalam suatu komponen menggunakan metode mapGetters yang disediakan oleh Vuex.


 import {mapGetters} from 'vuex'; computed : { ...mapGetters(['TODOS']), //    } 

Anda mungkin sudah menebak bahwa kode di dalam template harus diubah, seperti yang ditunjukkan pada snippet di bawah ini.


 <div class="todo-item" v-for="item in TODOS"></div> 

Perhatikan bagaimana kami menggunakan operator distribusi ES6 [...] di dalam properti yang dihitung.


PENYIMPANAN VUEX BUKAN HANYA SUMBER NEGARA SAAT INI DARI APLIKASI ANDA. ITU JUGA TITIK HANYA YANG HARUS MENGUBAH NEGARA INI.


Ini membutuhkan sedikit penjelasan. Kami telah belajar cara membuat tindakan untuk menerima dan menginstal item yang harus dilakukan di repositori kami. Bagaimana jika kita perlu memperbarui elemen dan menandainya? Di mana kita menjalankan kode untuk ini?


Di Internet Anda dapat menemukan berbagai pendapat tentang masalah ini. Dokumentasi juga tidak memiliki panduan yang jelas mengenai hal ini.


Saya akan merekomendasikan menyimpan semua panggilan API di dalam tindakan di repositori Vuex Anda. Dengan demikian, setiap perubahan status hanya terjadi di dalam repositori, sehingga memfasilitasi debugging dan menyederhanakan pemahaman kode, dan juga membuat pengeditan kode lebih mudah.



Organisasi Kode


Menyimpan semua variabel keadaan, getter, tindakan, dan mutasi dalam satu file akan dengan cepat membuatnya menjadi rumit segera setelah Anda mulai bekerja dengan aplikasi besar. Mari kita lihat bagaimana Anda dapat mengatur penyimpanan dalam beberapa file sebagai modul.


Buat direktori baru di dalam repositori Anda dan beri nama modul . Tambahkan file todos.js ke direktori yang dibuat yang berisi kode berikut:


 const state = {}; const getters = {}; const mutations = {}; const actions = {}; export default { state, getters, mutations, actions, }; 

Sekarang kita dapat memindahkan variabel keadaan, getter, mutasi dan tindakan dari file index.js ke file todos.js . Ingatlah untuk mengimpor Axios . Yang perlu kita lakukan adalah memberi tahu Vuex bahwa kita telah menciptakan modul penyimpanan dan di mana menemukannya. File index.js yang diperbarui akan terlihat seperti ini:


 import Vue from 'vue'; import Vuex from 'vuex'; import Axios from 'axios'; import todos from './modules/todos'; Vue.use(Vuex); export const store = new Vuex.Store({ state: {}, getters: {}, mutations: {}, actions: {}, modules: { todos, }, }); 

File todos.js akan terlihat seperti ini:


 import Axios from 'axios'; state = { todos: null, }; getters = { TODOS: state => { return state.todos; }, }; mutations = { SET_TODO: (state, payload) => { state.todos = payload; }, ADD_TODO: (state, payload) => { state.todos.push(payload); }, }; actions = { GET_TODO: async (context, payload) => { let {data} = await Axios.get('http://yourwebsite.com/api/todo'); context.commit('SET_TODO', data); }, SAVE_TODO: async (context, payload) => { let {data} = await Axios.post('http://yourwebsite.com/api/todo'); context.commit('ADD_TODO', payload); }, }; export default { state, getters, mutations, actions, }; 


Ringkasan


  1. Status aplikasi disimpan sebagai satu objek JSON besar.
  2. Getters digunakan untuk mengakses nilai yang disimpan di toko.
  3. Mutasi memperbarui kondisi Anda. Harus diingat bahwa mutasi itu sinkron.
  4. Semua operasi asinkron harus dilakukan dalam tindakan . Tindakan mengubah status, memulai mutasi.
  5. Buat aturan untuk memulai mutasi secara eksklusif melalui tindakan .
  6. Modul dapat digunakan untuk mengatur penyimpanan Anda dalam beberapa file kecil.

Vuex membuat bekerja dengan Vue lebih mudah dan lebih menyenangkan. Jika Anda seorang pemula, mungkin ada situasi di mana sulit bagi Anda untuk memutuskan apakah akan menggunakan Vuex di area tertentu dari aplikasi Anda. Ikuti insting Anda. Anda akan mencapai kecepatan tinggi dengan cukup cepat.

Source: https://habr.com/ru/post/id421551/


All Articles