我如何使用 Medusa 和 Ionic 创建电子商务应用程序
介绍
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 管理后台。请在另一个目录中运行以下命令:
git clone https://github.com/medusajs/admin medusa-admin
进入新创建的medusa-admin目录,并安装项目所需的依赖项:
cd medusa-admin
npm install
然后,要运行管理员程序,请在终端中执行以下命令:
npm run develop
这将运行 Medusa 管理程序localhost:7000。请确保 Medusa 服务器也仍在运行。
打开 Medusa 管理后台后,应该会看到登录页面。
由于您在上一节中使用了标志创建了一个 Medusa 服务器--seed,因此除了演示数据之外,还创建了一个测试用户。您可以使用该用户的电子邮件地址admin@medusa-test.com和密码supersecret登录。
Medusa 管理后台包含许多功能,例如查看订单、管理产品、配置商店和地区等等!
您可以尝试在 Medusa 管理后台编辑一些现有的演示产品或添加新产品。
初始化 Ionic 项目
在本节中,您将开始构建 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
这台机器上运行着 Ionic 开发服务器localhost:8100和 Ionic Lab localhost:8200。您可以使用 Ionic Lab 来模拟应用程序在不同设备(例如 iOS 或 Android)上的外观。
更改存储 CORS 变量
由于 Ionic 应用运行在 8100 端口,您需要将 Medusa 服务器上的 Store CORS 设置更新medusa-config.js到以下文件中:
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;
}
接下来,您将创建可重复使用的产品项目卡片组件。
现在接口已经定义并导出,是时候创建产品项目卡片的用户界面了。
创建一个新文件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属性的类型。
创建主布局
现在单个产品卡片的组件已经创建完成,接下来需要在首页布局屏幕中获取并渲染产品。
初始化 Ionic 项目时,默认情况下会创建`.js` 和` Home.tsx.js`文件。创建一个新目录,并将 `.js` 和 `.js` 文件移动到该目录中。Home.csssrc/pagessrc/pages/HomeHome.tsxHome.csssrc/pages/Home
编辑页眉
打开src/pages/Home/Home.tsx文件并查看返回的 JSX 代码,你会发现系统已自动添加了一个头部信息。你可以将组件中嵌套的文本替换IonTitle为你电商网站的名称。例如:
<IonHeader>
<IonToolbar>
<IonTitle>Medusa Ecommerce Store</IonTitle>
</IonToolbar>
</IonHeader>
从美杜莎服务器获取产品
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>组件创建产品项网格。
仍然在 ` <head>` 标签内src/pages/Home/Home.tsx,将以下内容添加到<IonContent>返回的 JSX 元素中,替换原有<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更新为 `<product> `。有关 Ionic 网格的更多信息,请务必查看官方文档。IonCol12
添加 CSS
修改内容src/pages/Home/Home.css以添加一些有用的样式:
.product_card {
cursor: pointer;
}
.product_title {
font-size: 1em;
}
测试主屏幕
请确保 Medusa 服务器仍在运行,如果 Ionic 服务器未运行,请重新运行 Ionic 服务器。
如果您现在在 Ionic lab 中打开该应用程序,您应该会在主屏幕上看到从 Medusa 服务器获取的产品。
请注意,由于系统设置,所示屏幕截图为深色模式。如果您使用浅色模式,屏幕显示效果会有所不同。
创建产品详情屏幕
在本节中,您将创建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。然后,axios使用该库向 Medusa 服务器上的“检索产品”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,然后点击主屏幕上的某个产品。此时会打开一个新页面,显示该产品的详细信息。
显示添加到购物车通知
在本节中,您将添加一个简单的弹出式通知,当点击“添加到购物车”按钮时会显示该通知。这实际上并不会将商品添加到购物车,而只是模拟该功能。
在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>
最后,修改“添加到购物车”按钮,添加onClick事件处理程序:
<IonButton class="button" size="default" shape="round" expand="block"
onClick={() => setShowToast(true)}>Add to Cart</IonButton>
现在,每当点击按钮时,该值showToast都会被设置为true显示 toast 通知。
测试通知
在 Medusa 和 Ionic 开发服务器仍在运行的情况下,在其中一个产品的详情页面点击“添加到购物车”按钮。随后会显示一个提示信息,持续几秒钟,表明该产品已添加到购物车。
接下来是什么?
通过按照本教程操作,您已成功将 Ionic 应用连接到 Medusa 服务器,并从服务器获取了产品。
您可以使用 Medusa 服务器在 Ionic 应用中添加更多功能,包括:
文章来源:https://dev.to/medusajs/how-i-created-an-ecommerce-app-with-medusa-and-ionic-2lkg如果您对 Medusa 有任何疑问或问题,请随时通过Discord联系 Medusa 团队 。







