Pinia/Vuex serta Redux direka untuk menjadi "sumber kebenaran tunggal" di mana anda boleh mempunyai satu atau lebih kedai untuk menyimpan data aplikasi yang boleh diperolehi dari mana-mana sahaja.
Kedai Pinia kelihatan seperti ini:
export let useProductsStore = defineStore('products', () => { let data = ref(products); function getList (params) { return someSearchStuffForProducts(params); } return {data, getList}; });
kemudian boleh digunakan sebagai:
let productsStore = useProductsStore(); console.log(data, data.value); productsStore.getList(params);
Kami boleh membuat beberapa kedai:
let usersStore = useUsersStore(); let productsStore = useProductsStore(); let basketStore = useBasketStore(); let favoritesStore = useFavoritesStore();
Kedai boleh merujuk antara satu sama lain:
export let useUsersStore = defineStore('users', () => { let productsStore = useProductsStore(); } export let useBasketsStore = defineStore('basket', () => { let productsStore = useProductsStore(); } //Et cetera
Akhir sekali, Pinia/Vuex ialah alatan yang menyediakan keupayaan untuk mendapatkan dan memanipulasi data yang disimpan dalam keadaan.
Tetapi terdapat satu lagi pendekatan matang: pengurus/kelas perkhidmatan.
Contoh sebelumnya boleh ditulis semula sebagai:
//Define the "single source of truth" let store = { products: { /* ... */}, currentUser: { /* ... */}, userBasket: { /* ... */}, userFavorites: { /* ... */}, }; //Here goes manager classes class ProductsManager { constructor (params) { this.state = params.state; //... } getList (params) { return someSearchStuffForProducts(params); } } class UsersManager { constructor (params) { this.state = params.state; //Products manager is injected as a dependency this.productsManager = params.productsManager; //... } } class BasketManager { constructor (params) { this.state = params.state; //Products manager is injected as a dependency this.productsManager = params.productsManager; //... } } //Some config/initialization script export let DIC = {}; //Container for manager instances DIC.productsManager = new ProductsManager({state: store.products}); DIC.usersManager = new usersManager({ state: store.currentUser, productsManager: DIC.productsManager, }); DIC.basketManager = new BasketManager({ state: store.userBasket, productsManager: DIC.productsManager, }); //Usage import {DIC} from './config'; DIC.productsManager.getList(); DIC.basketManager.add(someProductId); DIC.basketManager.changeCount(someProductId, 3);
Semua ini boleh ditaip dengan mudah dalam TypeScript tanpa memerlukan pembungkus tambahan, ref()
dll.
Daripada apa yang saya dapat tahu, Pinia kelihatan seperti "mencipta semula roda": menulis fungsi yang sama dengan cara yang kekok.
Selain itu, ia tidak memberikan suntikan pergantungan: anda tidak boleh memulakan stor dalam konfigurasi dan menyuntik satu kedai ke kedai lain dengan tepat, anda perlu lulus useProductsStore()
dan seterusnya.
Warisan atau apa-apa barangan OOP lain juga tidak boleh dilakukan.
Pinia malah menggalakkan kebergantungan bulat, menghasilkan kod spageti dengan kebolehselenggaraan yang lemah
Jadi, selepas semua, mengapa seseorang harus memilih Pinia/Vuex berbanding pendekatan OOP bersih yang telah dicuba dan diuji dengan kelas pengurus? Saya telah menghabiskan berpuluh-puluh jam menulis projek tutorial ciptaan saya sendiri menggunakan Pinia sebagai "pengurusan negeri Vue yang disyorkan seterusnya", dan kini saya terdorong untuk menulis semula semuanya ke dalam kelas pengurus kerana saya mendapati Pinia kikuk dan kaya . Saya baru teringat bahawa beberapa tahun lalu saya sedang menulis projek ujian lain - menggunakan Vue2 - dan pada masa itu saya menggunakan kelas pengurus - dan semuanya berjalan lancar. Adakah saya terlepas pandang sesuatu? Adakah akan ada masalah jika saya melepaskan Pinia?
Kelas ialah warga kelas kedua dalam kereaktifan Vue, dan terdapat beberapa masalah. Hakikat bahawa mereka tidak boleh diikat dalam pembina
this
,这将导致使用非反应式类实例反应式代理。他们无法有效地使用引用,因为这些引用是在记录但异常的方式。他们无法使用 get/set 访问器来计算引用。这些问题需要显式使用 Vue 反应性 API 以奇怪的方式编写类,或者以受限制的方式设计类,因此reactive(new MyClass)
tidak menghalangnya daripada berfungsi dengan betul.Kelas tidak mempunyai ciri yang dimiliki oleh kedai, seperti sokongan meluas untuk alat pembangunan Vue, sistem pemalam, dsb.
Kelas juga tidak boleh bersiri dalam JavaScript, jadi menyimpan dan memulihkan keadaan memerlukan logik tersuai dan bukannya pensirilan JSON (de) mudah seperti dalam pemalam kegigihan storan.
Suntikan ketergantungan tidak unik untuk kelas dan boleh dilakukan dengan cara yang sesuai, contohnya untuk kedai Pinia:
Dalam banyak kes, adalah lebih baik untuk berurusan dengan Pinia yang menyimpan bahan boleh gubah daripada menyimpan contoh kerana ini menyelesaikan kebergantungan bulat yang boleh menjadi masalah jika boleh gubah dipanggil lebih awal. Masalah yang sama boleh berlaku dengan kelas, dan memerlukan penggunaan bekas DI dan bukannya menggunakan contoh kelas secara langsung.
Warisan tiada masalah kerana kod boleh guna semula boleh dikendalikan dengan FP dan bukannya OOP. Vue tidak mempromosikannya secara eksplisit, tetapi menjadikan yang pertama lebih idiomatik dan selesa untuk digunakan.
TL;DR: Lekatkan dengan objek biasa dan FP kerana ini adalah kes utama untuk reka bentuk reaktif Vue.