Pinia/Vuex
Pinia/Vuex和Redux都被设计成"单一的真理来源",在那里你有一个或多个store 保存应用程序数据,从任何地方都可以获得.
一家Piniastore 看起来是这样的:
export let useProductsStore = defineStore('products', () => {
let data = ref(products);
function getList (params) {
return someSearchStuffForProducts(params);
}
return {data, getList};
});
则可用作:
let productsStore = useProductsStore();
console.log(data, data.value);
productsStore.getList(params);
我们可以创建多个store :
let usersStore = useUsersStore();
let productsStore = useProductsStore();
let basketStore = useBasketStore();
let favoritesStore = useFavoritesStore();
store 之间可以相互指代:
export let useUsersStore = defineStore('users', () => {
let productsStore = useProductsStore();
}
export let useBasketsStore = defineStore('basket', () => {
let productsStore = useProductsStore();
}
//Et cetera
最后,Pinia/Vuex是提供检索和操作存储在状态中的数据的功能的工具.
管理器/服务类
但还有另一种成熟的方法:管理器/服务类.
前面的示例可以重写为:
//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);
所有这些都可以很容易地以打印稿的形式输入,而不需要额外的包装器、ref()
等.
讨论
在我看来,Pinia看起来就像是"重新发明了轮子":以一种笨拙的方式编写了相同的功能.
此外,它不提供依赖注入:您不能在配置中注入存储并准确地将一个存储注入到另一个存储中,您必须将依赖项直接硬编码到存储中,按useProductsStore()
或类似的方式编码.
继承或任何其他面向对象的东西也是不可能的.
Pinia甚至promotes个循环依赖,这导致了可维护性较差的意大利面代码.
那么,毕竟,为什么人们应该更喜欢Pinia/Vuex,而不是经过战斗考验的、干净的OOP方法和经理类?我已经花了几十个小时编写我自己发明的教程项目,使用Pinia作为"Vue的下一个推荐的状态管理",现在我很想把所有东西重写到Manager类中,因为我发现Pinia既笨拙又丰富.我只是回忆起几年前我在编写另一个测试项目时--使用Vue2--当时我使用的是管理器类--一切都很顺利.我是不是忽略了什么?如果我放弃皮尼亚,我会有问题吗?