当使用群岛结构 / 部分激活构建一个 Astro 网站时,你可能会遇到这样的问题:我想在我的组件之间共享状态。
像 React 或者 Vue 这样的 UI 框架可能鼓励使用 “context” 来为其他组件提供上下文信息。但是在 Astro 或者 Markdown 中的 部分激活组件 (partially hydrating components) 不能使用上下文封装。
Astro 推荐了一个不同的客户端共享存储的解决方案: Nano Stores。
Nano Stores 库允许你编写任何组件都能与之互动的状态库。我们推荐 Nano Stores,因为:
- 它是轻量级的。 Nano Stores 提供了你所需要的最低限度的 JS(不到 1KB),并且零依赖。
- 它是框架无关的。 这意味着在框架之间共享状态将是无缝的!Astro 是建立在灵活性之上的,所以我们喜欢那些无论你的偏好如何都能提供类似开发者体验的解决方案。
尽管如此,你仍然可以探索一些替代方案。这些方法包括:
为你喜欢的 UI 框架安装 Nano Stores 和他们的帮助包:
你可以跳转到 Nano Stores 使用指南 或者跟随我们下面的例子!
假如我们正在搭建一个简单的电商页面,有下面三个交互元素:
- 一个 “add to cart” 按钮
- 一个购物车抽屉来显示已添加的商品
- 一个购物车抽屉开关
在你的机器上尝试完整的例子 或者通过 StackBlitz 在线尝试!
你基础的 Astro 文件看起来应该是这样的:
让我们在点击购物车抽屉开关(CartFlyoutToggle
)的时候打开购物车抽屉(CartFlyout
)
首先,创建一个新的 JS 或 TS 文件来存放我们的状态库。我们将会使用 “atom” 来做这件事:
现在,我们可以在任意文件中导入这个状态库来进行读写。我们接下来着手开发我们的 CartFlyoutToggle
组件:
然后,我们可以从我们的 CartFlyout
组件中读取 isCartOpen
值:
现在,让我们来跟踪你购物车里的商品。为了避免重复和跟踪 “数量”,我们可以把你的购物车存储为一个对象,以商品的 ID 为键。我们将使用一个 Map 来做这件事。
让我们在先前的 cartStore.js
中添加一个 cartItem
状态库。如果你愿意的话,你也可以使用 TypeScript 文件来定义。
现在,让我们导出一个 addCartItem
函数供我们的组件使用。
- 如果你的购物车中不存在该商品,添加商品并设置初始数量 1。
- 如果购物车中 已经 存在该商品,则将该商品数量增加 1。
有了状态库之后,我们就可以在每次提交表单时调用 AddToCartForm
函数。我们还可以打开购物车抽屉,这样你就可以看到一个完整的购物车概要。
最后,我们将在 CartFlyout
组件中渲染购物车商品:
现在,你应该拥有了一个完全交互式的电商示例,并且是宇宙中最小的 JS 包 🚀
在你的机器上尝试完整的例子 或者通过 StackBlitz 在线尝试!
Recipes