Vue 3 + Pinia 中的业务逻辑

问题描述 投票:0回答:1

假设我有一个使用 Vue 3 的简单网上商店应用程序。每当用户将商品添加到购物车时,我都会将其存储在 Pinia 本地,并将此事件信息发送到后端。

默认情况下,我会向 Pinia 存储添加一个操作,如

addItemToCart()
,它将更新本地
cartItems
反应变量,并将请求发送到后端,如
POST http://localhost/api/update-cart

我的想法是在我的应用程序中引入一个服务层。 我会创建一个类似的服务:

const useCartService = () => {
  const cartStore = useCartStore()

  const updateCartApi = useUpdateCartApi()

  const addItemToCart = async (item) => {
    cartStore.loading = true

    await updateCartApi.mutate(item)

    cartStore.items.push(item)

    cartStore.loading = false
  }

  return {
    loading: cartStore.loading,
    
    addItemToCart,
  }
}

像这样将业务逻辑与 Pinia 商店分开有意义吗?它是否被视为反模式,或者这种方法在 Vue 中常用?

vue.js nuxt.js vuejs3 pinia
1个回答
0
投票
await updateCartApi.mutate(item)

cartStore.items.push(item)

这不是假的,而是错误的:

  • 'updateCartApi.mutate(item)'返回错误或答案
  • 'cartStore.items.push(item)' 会增加您的购物车,无论后端是否允许,从而可能导致未处理的缺货(特别是如果两个或更多用户同时将相同的 LAST 产品添加到购物车时)

这通常是实现该逻辑的地方,例如:

// if the api call returns the item
await updateCartApi.mutate(item).then((answer)=>{
    cartStore.items.push(answer)    
}).catch((e)=>{
    // ~ toast error message or console.log(e)
    productStore.byId(item.id).amount=0 //byId should be a getter
    //the business logic ...
})

// if the api call returns the cart content
await updateCartApi.mutate(item).then((answer)=>{
    cartStore.items.splice(0)
    cartStore.items.push(...answer)    
}).catch((e)=>{
    // ~ toast error message or console.log(e)
    productStore.byId(item.id).amount=0 //byId should be a getter
    //the business logic ...
})

总体而言,您的代码易于阅读,并且嵌套存储非常适合需要私有的存储。

PS:为了可读性,我个人会推荐组合存储而不是选项存储,但这取决于你;)

© www.soinside.com 2019 - 2024. All rights reserved.