介绍
Ionic是一个开源工具包,允许开发人员创建支持各种移动平台(包括 Android 和 iOS)的跨平台应用程序。开发人员可以使用他们选择的前端框架进行构建,包括 Angular、Vue 和 React。
Medusa是一个开源的可组合电子商务平台,允许开发人员创建自己的可定制和可扩展的在线商店。Medusa 旨在为开发人员提供创建独特电子商务商店的绝佳体验。
在本教程中,您将使用 Medusa 和 Ionic 构建一个电子商务应用程序。该应用程序随后可以在 Android、iOS 和 Windows 手机等手机上使用,也可以用作渐进式 Web 应用程序 (PWA)。
您可以在 GitHub 上的此存储库中查看教程的源代码。

先决条件
要使用 Medusa,您需要在您的机器上安装 Node.js(版本 14+)。您可以从官方Node.js 网站下载它。
设置美杜莎服务器
首先,通过在终端中运行以下命令来安装 Medusa CLI:
npm install -g @medusajs/medusa-cli
接下来,运行以下命令来创建一个新的 Medusa 服务器:
medusa new ecommerce-store-server --seed
该--seed
标志使用演示数据填充数据库,然后可以将其用作电子商务商店的一部分。
最后,导航到ecommerce-store-server
目录并启动服务器:
cd ecommerce-store-server
medusa develop
如果服务器成功运行,您应该会在终端中看到类似于以下内容的输出:

安装Medusa Admin
接下来,是时候设置和运行 Medusa Admin 仪表板了。在单独的目录中,运行以下命令:
git clone https://github.com/medusajs/admin medusa-admin
导航到新创建的medusa-admin目录并安装项目的依赖项:
cd medusa-admin
npm install
然后,要运行管理员,请在终端中执行以下命令:
npm run develop
这会在localhost:7000. 确保 Medusa 服务器也仍在运行。
如果您打开 Medusa Admin,您应该会看到一个登录页面。

由于您在上一节中使用--seed标志创建了 Medusa 服务器,因此除了演示数据之外还创建了一个测试用户。因此,您可以使用电子邮件admin@medusa-test.com和密码supersecret登录。
Medusa 管理员包括许多功能,例如查看订单、管理产品、配置您的商店和区域等等!
您可以尝试在 Medusa 管理器中编辑一些现有的演示产品或添加新产品。

初始化一个离子项目
在本节中,您将开始构建 Ionic 应用程序。
首先,通过运行以下命令安装 Ionic CLI:
npm install -g @ionic/cli
然后,在一个单独的目录中,使用以下命令创建一个新的 Ionic 应用程序:
ionic start ecommerce-store blank --type=react
本教程使用 React 创建 Ionic 应用程序。这被指定为上面带有--type
标志的命令的一部分。
安装项目所需的所有依赖项通常需要几分钟时间。
安装完成后,切换到ecommerce-store
目录并安装所需的其他依赖项:
cd ecommerce-store
npm install axios
axios
用于向 Medusa 服务器发送异步请求。这将允许您执行诸如获取产品之类的操作。
测试 Ionic 应用程序
要测试空白的 ionic 应用程序,请在终端中运行以下命令:
ionic serve --lab
这运行了一个开发离子服务器localhost:8100
和离子实验室localhost:8200
。您可以使用 Ionic Lab 来模拟应用在不同设备(如 iOS 或 Android)上的外观。

更改存储 CORS 变量
由于 Ionic 应用程序在端口 8100 上运行,因此您需要将medusa-config.js
文件中 Medusa 服务器上的 Store CORS 设置更新为以下内容:
const STORE_CORS = process.env.STORE_CORS || "http://localhost:8100"
有关更多信息,请查看有关更新 CORS 设置的官方指南。
确保在进行此更改后重新启动美杜莎服务器。
创建产品项目卡
在本节中,您将创建一个可重用的组件,以在主页上将产品显示为卡片。
首先,您需要创建两个界面,一个用于产品,另一个用于图像。这些接口将用于定义产品和图像的结构。
为此,请创建src/Interfaces.tsx
具有以下内容的文件:
export interface Product {
id: string;
title: string;
handle: string;
images: Image[];
description: string;
variants: any[];
}
export interface Image {
url: string;
}
接下来,您将创建可重复使用的产品项目卡组件。
现在接口已定义并导出,是时候为产品项卡创建 UI。
创建一个src/components/ProductItemCard/ProductItemCard.tsx
包含以下内容的新文件:
import React, { useEffect } from 'react';
import { IonCard, IonCardHeader, IonCardSubtitle, IonImg, IonCardTitle } from '@ionic/react';
import { Product } from '../../Interfaces';
const ProductItemCard = ({ product }: { product: Product }) => {
return (
<div>
{product && (
<IonCard routerLink={"/product/" + product["id"]} className="product_card">
<IonImg src={product.images[0]["url"]} class="image" />
<IonCardHeader>
<IonCardTitle className="product_title"><b>{product["title"]}</b></IonCardTitle>
<IonCardSubtitle>{product["handle"]}</IonCardSubtitle>
<IonCardSubtitle>${product["variants"][0]["prices"][1]["amount"] / 100}</IonCardSubtitle>
</IonCardHeader>
</IonCard>
)}
</div>
);
};
export default ProductItemCard;
每张卡片显示产品的图像、标题、类型和价格。一个产品道具将被传递给组件,然后显示其相应的元数据。该Product
接口用于强制执行product
道具的类型。
创建主页布局
现在已经创建了单个产品卡的组件,是时候在主页布局屏幕中获取和呈现产品了。
Home.tsx
和文件在初始化 Ionic 项目时Home.css
默认创建。src/pages
创建一个新目录src/pages/Home
并移动Home.tsx
并Home.css
进入该src/pages/Home
目录。
编辑标题
如果您打开src/pages/Home/Home.tsx
文件并查看返回的 JSX,您会看到已自动为您添加了一个标头。您可以将嵌套在组件中的文本替换IonTitle
为您的电子商务商店的名称。例如:
<IonHeader>
<IonToolbar>
<IonTitle>Medusa Ecommerce Store</IonTitle>
</IonToolbar>
</IonHeader>
从 Medusa 服务器获取产品
创建src/server-url.js
具有以下内容的文件:
const medusaServerBaseURL = "http://localhost:9000";
export default medusaServerBaseURL;
在一个文件中定义 Medusa 服务器的基本 URL 很有用。然后,如果需要更新端口或 URL,则只需更新此文件中的 URL。
如果您在移动设备上进行测试,则应将 URL 更改为您机器的 IP。
接下来,在 中src/pages/Home/Home.tsx
,将文件开头的导入替换为以下内容:
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar, IonGrid, IonRow, IonCol, } from '@ionic/react';
import './Home.css';
import React, { useEffect, useState } from 'react';
import axios from "axios";
import ProductItemCard from '../../components/ProductItemCard/ProductItemCard';
import medusaServerBaseURL from "../../server-url";
然后,在组件内部创建一个状态变量Home
来存储产品:
const [products, setProducts] = useState([]);
并在创建状态变量后添加以下内容:
useEffect(() => {
axios
.get(`${medusaServerBaseURL}/store/products`)
.then((response) => {
if (response.data) {
let products = response.data.products;
setProducts(products);
}
})
.catch((err) => {
console.log("error", err)
});
}, []);
使用useEffect
时,Home 组件将在屏幕首次打开时从服务器获取产品。axios
向List Products端点发送一个请求。然后,结果用于设置products
状态变量。
创建产品网格
接下来,是时候使用该<IonGrid>
组件创建产品项目网格了。
仍然在 中src/pages/Home/Home.tsx
,在返回的 JSX 的元素中添加以下内容<IonContent>
,替换<ExploreContainer>
组件:
<IonGrid class="ion-no-padding ion-no-margin">
<IonRow>
{products.map((product, i) =>
<IonCol size="6">
<ProductItemCard product={product} />
</IonCol>)}
</IonRow>
</IonGrid>
ProductItemCard
此网格使用组件呈现每个产品。每行显示两个产品,但如果您想将其更改为每行一个产品,请将元素的size
prop更新为. 有关 Ionic 中网格的更多信息,请务必查看官方文档。IonCol``12
添加 CSS
更改的内容src/pages/Home/Home.css
以添加一些有用的样式:
.product_card {
cursor: pointer;
}
.product_title {
font-size: 1em;
}
测试主屏幕
确保 Medusa 服务器仍在运行,如果 Ionic 服务器未仍在运行,请重新运行它。
如果您现在在 Ionic 实验室中打开该应用程序,您应该会在主屏幕上看到从您的 Medusa 服务器获取的产品。
请注意,由于系统偏好,显示的屏幕截图处于暗模式。如果您使用灯光模式,屏幕看起来会有所不同。

创建 ProductDetail 屏幕
在本节中,您将创建ProductDetail
屏幕。此屏幕将显示单个产品的信息和图像。
创建src/pages/ProductDetailPage/ProductDetailPage.tsx
具有以下内容的文件:
import { IonContent, IonHeader, IonPage, IonTitle, IonToolbar } from '@ionic/react';
import './ProductDetailPage.css';
import React, { useEffect, useState } from 'react';
import { IonCard, IonCardHeader, IonBackButton, IonButtons, IonCardSubtitle, IonToast, IonImg, IonCardTitle, IonCardContent, IonButton } from '@ionic/react';
import axios from "axios";
import { RouteComponentProps } from 'react-router-dom';
import { Product } from '../../Interfaces';
import medusaServerBaseURL from "../../server-url";
const ProductDetailPage: React.FC<RouteComponentProps<{ id: string }>> = (props) => {
const [product, setProduct] = useState<Product>();
useEffect(() => {
let product_id = props.match.params.id;
axios
.get(`${medusaServerBaseURL}/store/products/${product_id}`)
.then((response) => {
if (response.data.product) {
setProduct(response.data.product);
}
})
.catch((err) => {
console.log("error", err)
});
}, [props.match.params.id])
return (
<IonPage>
<IonHeader>
<IonToolbar>
<IonButtons slot="start">
<IonBackButton text="">
</IonBackButton>
</IonButtons>
<IonTitle>Medusa Ecommerce Store</IonTitle>
</IonToolbar>
</IonHeader>
<IonContent fullscreen>
{product && (
<IonCard mode="ios">
{product["images"] && (
<IonImg class="product_detail_img" src={product.images[0]["url"]} />
)}
<IonCardHeader>
<div className="metaInfo">
<IonCardTitle>{product["title"]}</IonCardTitle>
<IonCardSubtitle>{product["handle"]}</IonCardSubtitle>
<h3>${product["variants"][0]["prices"][1]["amount"] / 100}</h3>
</div>
</IonCardHeader>
<IonCardContent>
<h3>Description</h3>
{product["description"]}
<IonButton class="button" size="default" shape="round" expand="block">Add to Cart</IonButton>
</IonCardContent>
</IonCard>
)}
</IonContent>
</IonPage>
);
};
export default ProductDetailPage;
在此页面中,产品 ID 是从路由参数中检索的。然后,该库用于向 Medusa 服务器上的Retrieve Product端点axios
发送请求,以检索单个产品的数据。然后,使用请求的响应设置状态变量。product
接下来,创建src/pages/ProductDetailPage/ProductDetailPage.css
具有以下内容的文件:
.product_detail_img {
height: 30vh;
object-fit: cover;
}
@media (prefers-color-scheme: light) {
h3 {
color: black;
}
}
h3 {
font-weight: bold;
}
.button {
margin-top: 1em;
}
.metaInfo {
display: flex;
flex-direction: column;
flex-wrap: wrap;
}
添加新路线
要实际使用新屏幕,必须将其添加为应用程序中的新路线。
首先,将ProductDetailPage
组件导入src/App.tsx
:
import ProductDetailPage from './pages/ProductDetailPage/ProductDetailPage';
然后,将新路由添加到定义的路由列表中App
:
const App: React.FC = () => (
<IonApp>
<IonReactRouter>
<IonRouterOutlet>
<Route exact path="/home">
<Home />
</Route>
<Route exact path="/">
<Redirect to="/home" />
</Route>
<Route path="/product/:id/" component={ProductDetailPage} />
</IonRouterOutlet>
</IonReactRouter>
</IonApp>
);
测试产品详细信息屏幕
在 Medusa 和 Ionic 开发服务器仍在运行时,在浏览器中打开 Ionic Lab 并单击主屏幕中的其中一个产品。将打开一个新屏幕,显示产品的详细信息。

显示加入购物车通知
在本节中,您将在单击“添加到购物车”按钮时添加一个简单的 toast 通知。这实际上并没有将产品添加到购物车,而只是模拟了功能。
在src/pages/ProductDetailPage/ProductDetailPage.tsx
文件中,在创建状态变量后添加以下内容,product
以创建一个新的状态变量来管理 toast 通知的可见性:
const [showToast, setShowToast] = useState(false);
然后,IonToast
在返回的 JSX 中添加一个组件。它应该放置在组件内部IonContent
和之后IonCard
:
<IonContent fullscreen>
{product && (
<IonCard mode="ios">
...
</IonCard>
)}
<IonToast
isOpen={showToast}
onDidDismiss={() => setShowToast(false)}
message="Product added to cart"
duration={800}
/>
</IonContent>
最后,更改 Add to Cart 按钮以添加onClick
事件处理程序:
<IonButton class="button" size="default" shape="round" expand="block"
onClick={() => setShowToast(true)}>Add to Cart</IonButton>
现在,每当单击按钮时, 的值showToast
都会设置为true
显示 toast 通知。
测试通知
当 Medusa 和 Ionic 开发服务器仍在运行时,在其中一种产品的详细信息屏幕上单击“添加到购物车”按钮。然后会显示一个 toast 通知几秒钟,表明产品已添加到购物车。

链接:https://dev.to/medusajs/how-i-created-an-ecommerce-app-with-medusa-and-ionic-2lkg
网友评论