如何使用 Node.js 后端构建 Vue.js 电子商务商店
美杜莎
电子商务并非易事。除了在前端打造出色的客户体验外,您还需要正确的设置来处理所有购物车、客户和订单数据、产品信息等……
在本教程中,您将了解到如何做到这一点!
在本教程中,您将了解打造卓越电商体验所需的必要前提条件。Vue.js 是前端框架的绝佳选择,因为它是开源的,采用基于组件的架构,并且具有响应式特性 。
对于后端,您将学习如何使用 Medusa ,这是一个开源 Node.js 商务引擎,它附带所有必要的电子商务功能,包括易于导航的管理系统。
此 Vue.js 项目的完整代码位于 此 GitHub 仓库 。以下是最终结果的简要预览。
什么是 Vue.js
Vue.js 是一个开源的渐进式 JavaScript 框架。它可以用于构建各种类型的应用程序,包括网站、移动应用程序和桌面应用程序。这可以通过将 Vue.js 与其他平台(例如 Electron 或 Ionic)结合使用来实现。
Vue.js 自发布以来,凭借其众多优势而人气飙升。它易于学习和使用,拥有简洁的文档和流畅的学习曲线。此外,它体积小巧,采用响应式系统,并采用基于组件的可复用架构。
美杜莎是什么
美杜莎
数字商务的基石
入门
访问 文档 来设置 Medusa 应用程序。
美杜莎是什么
Medusa 是一个内置可定制框架的电商平台,让您无需重新设计核心商务逻辑即可构建自定义商务应用。该框架和模块可用于构建高级 B2B 或 DTC 电商商店、平台、PoS 系统、服务型企业,或任何需要基础商务功能的产品。所有商务模块均为开源模块,可在 npm 上免费获取。
在文档中 了解有关 Medusa 的架构 和 商业模块的更多信息。
升级与集成
按照 发行说明 来保持您的 Medusa 项目保持最新。
查看所有 可用的 Medusa 集成 。
社区与贡献
社区和核心团队可以在 GitHub Discussions 中找到,您可以在那里寻求支持、讨论路线图和分享想法。
我们的 贡献指南 描述了如何为……做出贡献。
Medusa 是 GitHub 上排名第一的开源 Node.js 商务平台。其可组合和无头架构使其能够与任何技术栈集成,从而构建跨平台电商商店,涵盖 Web、Android 和 iOS 应用。
Medusa 允许开发者构建可扩展且易于维护的电商商店。它提供许多高级电商功能,例如管理商店仪表板、产品配置、手动下单、多币种支持等等。此外,它还可以轻松集成各种 支付方式 、 CMS 和配送选项。
如果您喜欢该工具,请加星标🌟
先决条件
在开始之前,请确保您拥有 Node.js 版本 14 或更高版本。
使用 Medusa Commerce Engine 创建服务器
要在本地计算机上设置 Medusa 服务器,请按照以下部分概述的步骤进行操作。
安装 Medusa CLI 工具
Medusa CLI 可以使用 npm
或来安装 yarn
,但本教程使用 npm
。运行以下命令安装 Medusa CLI:
npm install @medusajs/medusa-cli -g
Enter fullscreen mode
Exit fullscreen mode
创建新的 Medusa 商店服务器
要创建新的 Medusa 商店服务器,请运行以下命令:
medusa new my-medusa-store --seed
Enter fullscreen mode
Exit fullscreen mode
注意: my-medusa-store
代表项目名称;您可以将其更改为您喜欢的项目名称。
如果您成功创建了新的 Medusa 项目,您应该会得到类似于以下屏幕截图的结果。
测试您的 Medusa 服务器
要测试您的 Medusa 服务器,请切换到新创建的目录并 develop
使用 Medusa 的 CLI 运行命令:
cd my-medusa-store
medusa develop
Enter fullscreen mode
Exit fullscreen mode
localhost:9000/store/products/
您可以通过发送列出商店中可用产品的 请求来测试它。
Medusa Admin 安装
要设置您的 Medusa Admin,请按照以下步骤操作。
克隆 Medusa Admin 存储库:
git clone https://github.com/medusajs/admin medusa-admin
cd medusa-admin
Enter fullscreen mode
Exit fullscreen mode
运行以下命令来安装所有必要的依赖项:
npm install
Enter fullscreen mode
Exit fullscreen mode
测试一下:
npm start
Enter fullscreen mode
Exit fullscreen mode
Medusa Admin 默认运行在端口 上 7000
。您可以 localhost:7000
通过浏览器访问管理页面。
由于您 --seed
在安装 Medusa 服务器时包含了该选项,因此已创建一个虚拟管理员用户。其邮箱地址为 admin@medusa-test.com
,密码为 supersecret
。
使用 Medusa 后台,您可以为商店创建新产品和系列。您还可以在后台编辑、取消发布、复制和删除产品。
您可以访问 用户指南 来了解有关 Medusa Admin 的更多信息。
创建新的 Vue.js 项目
接下来是为电商项目创建并设置一个新的 Vue.js 项目。您可以运行以下命令来设置一个新的 Vue.js 项目:
npm init vue@latest
Enter fullscreen mode
Exit fullscreen mode
此命令将安装并执行 create-vue —— Vue 官方项目脚手架工具。你将看到一些可选功能的提示,例如 TypeScript 和测试支持。
确保选择与上面屏幕截图中相同的选项。
项目创建完成后,使用以下命令安装必要的依赖项:
cd vuejs-ecommerce
npm install
Enter fullscreen mode
Exit fullscreen mode
Tailwind CSS 安装
Tailwind CSS 是一个 CSS 框架,可让您轻松设计电商店面的样式。在本教程中,您将在 Vue.js 电商店面中使用 Tailwind CSS。
在 vuejs-ecommerce
目录中,运行以下命令安装 Tailwind CSS:
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
Enter fullscreen mode
Exit fullscreen mode
上述命令将在你的 Vue.js 项目中生成 tailwind.config.js
和 postcss.config.js
文件。
配置模板路径
在您的 tailwind.config.js
文件中, content
用以下代码片段替换数组:
content : [
" ./index.html " ,
" ./src/**/*.{js,ts,jsx,tsx,vue} " ,
],
Enter fullscreen mode
Exit fullscreen mode
将 Tailwind 指令添加到你的 CSS
转到 src/assets/main.css
并使用以下代码片段替换整个代码:
@tailwind base ;
@tailwind components ;
@tailwind utilities ;
Enter fullscreen mode
Exit fullscreen mode
该 base
层处理诸如重置规则或应用于纯 HTML 元素的默认样式之类的事情。
该 components
层处理您希望能够使用实用程序覆盖的基于类的样式。
该 utilities
层处理小型、单一用途的类,这些类应始终优先于任何其他样式。
您可以访问 Tailwind CSS 文档 以了解更多信息。
将 Vue.js 电商店面与 Medusa 集成
在本节中,您将准备将 Vue.js 电子商务店面与 Medusa 服务器集成,以便稍后与 API 进行交互。
创建基本 URL 环境变量
环境 baseURL
变量是您的 Medusa 服务器的 URL。 .env
在 vuejs-ecommerce
目录中创建一个包含以下内容的文件:
VITE_baseUrl=http://localhost:9000
Enter fullscreen mode
Exit fullscreen mode
注意:如果由于任何原因,您更改了 Medusa 服务器的默认端口号,则必须 9000
在此处将其更改为您的端口号。
在 Vue.js 项目中安装 Axios
您将使用 Axios 向 Medusa 服务器发送请求。您可以通过运行以下命令来安装 Axios:
npm i axios
Enter fullscreen mode
Exit fullscreen mode
现在已经安装了 Axios,下一步是将 Medusa API 集成到您的项目中。
为您的 Vue.js 项目创建组件
在本部分中,您将创建诸如 Header
、 Footer
和 Products
等组件。这些组件将用于店面的不同页面。
一些组件会使用图片来实现更好的店面设计。您可以在 GitHub 仓库 中找到本项目使用的所有图片。
页眉组件
创建文件 src/components/PageHeader.vue
并向其中添加以下代码:
< template >
< div >
< div class = "fixed z-50 bg-white topNav w-full top-0 p-3 md:bg-opacity-0" >
< div class = "max-w-6xl relative flex mx-auto flex-col md:flex-row" >
< a href = "" class = "md:hidden absolute top-1 right-14" >
< div class = "relative" >
< img src = "/src/images/icon.png" class = "bottom-1 cursor-pointer relative" >
< div class = "absolute px-1 bg-red-500 -top-1 -right-1 rounded-full border-2 border-white text-white" id = "cart2" style = "font-size: 10px" ></ div >
</ div >
</ a >
< div class = "absolute h-10 flex justify-center bars items-center w-10 text-white right-1 -top-2 rounded-lg shadow-lg md:hidden cursor-pointer border-2 border-white bg-red-500" >
< i class = "fa fa-bars" ></ i >
</ div >
< div class = "flex-grow font-bold text-lg" >
< router - link : to = "{ name: 'home'}" >
< span class = "" > Noble's Shop</ span >
</ router - link >
</ div >
< div class = "menu hidden md:flex flex-col md:flex-row mt-5 md:mt-0 gap-16" >
< div class = "flex flex-col md:flex-row gap-12 capitalize" >
< div class = "" >
< router - link : to = "{ name: 'home'}" >
< span class = "text-red-400 font-bold border-b border-red-400" > home</ span >
</ router - link >
</ div >
< div class = "" >
< router - link : to = "{ name: 'products'}" >
< span class = "" > products</ span >
</ router - link >
</ div >
</ div >
< div class = "flex gap-12" >
< a href = "#" class = "hidden md:block" >
< div class = "relative" >
< img src = "/src/images/icon.png" class = "bottom-1 cursor-pointer relative" >
< div v-if = "productId.length > 0" class = "absolute px-1 bg-red-500 -top-1 -right-1 rounded-full border-2 border-white text-white" id = "cart" style = "font-size: 10px" > { { productId . length } } </ div >
</ div >
</ a >
</ div >
</ div >
</ div >
</ div >
</ div >
</ template >
< script >
export default {
props :{
productId : Array
}
}
</ script >
Enter fullscreen mode
Exit fullscreen mode
上述代码块涵盖了该项目的标题页。它包括页面路由、网站名称和购物车图标。
该组件稍后将添加到 src/App.vue
该项目中,以便在该店面的每个页面上添加标题。
页脚组件
src/components/FooterComponent.vue
创建包含以下内容的 文件:
< template >
< div >
< div class = "bg-purple-300 py-32 px-4 gap-y-20 justify-center items-center" >
< div class = "font-extrabold text-4xl text-center space-y-3" >
< div class = "" > Join Our Wait List And Get</ div >
< div class = "text-red-custom" > Discount Up to 50%</ div >
< div class = "" >
< div class = "py-1 flex relative max-w-xl mx-auto" >
< input type = "text" placeholder = "Enter Your Email Here" class = "text-sm border w-full pr-52 focus:ring-red-400 focus:border-red-400 relative px-5 placeholder-gray-400 py-6 -right-1 border-red-400 rounded-lg flex-grow" >
< span class = "bg-btn-color absolute text-base -right-1 uppercase rounded-lg z-10 text-white px-16 py-6 bg-opacity-25" style = "top: 5px" >
sign in
</ span >
</ div >
</ div >
</ div >
</ div >
< div class = "bg-purple-800 py-32 PX-4" >
< div class = "max-w-6xl gap-6 mx-auto grid grid-cols-1 md:grid-cols-9" >
< div class = "md:col-span-3 py-3 space-y-4" >
< div class = "text-2xl font-bold text-gray-100" > Noble's Shop</ div >
< div class = "text-gray-300 w-60 pr-0" > We sell only but quality and first grade Hoddies, Joggers, Shorts and lot more.</ div >
</ div >
< div class = "md:col-span-2 py-3 space-y-4" >
< div class = "text-2xl font-bold text-gray-100" > Information</ div >
< div class = "text-gray-300 w-60 space-y-2 pr-0" >
< div class = "" > About Us</ div >
< div class = "" > More Search</ div >
< div class = "" > Online Order</ div >
< div class = "" > Support</ div >
</ div >
</ div >
< div class = "md:col-span-2 py-3 space-y-4" >
< div class = "text-2xl font-bold text-gray-100" > Our Services</ div >
< div class = "text-gray-300 w-60 space-y-2 pr-0" >
< div class = "" > Clothing</ div >
< div class = "" > Fashion</ div >
< div class = "" > Design</ div >
< div class = "" > Privacy</ div >
</ div >
</ div >
< div class = "md:col-span-2 py-3 space-y-4" >
< div class = "text-2xl font-bold text-gray-100" > Contact Us</ div >
< div class = "text-gray-300 w-60 space-y-2 pr-0" >
< div class = "" > +234 098-897-8888</ div >
< div class = "" > info@domain-name.com</ div >
< div class = "" > Terms & Condition</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
</ template >
Enter fullscreen mode
Exit fullscreen mode
在上面的组件中,您介绍了此电商应用页脚页面的所有内容。稍后您将在需要添加页脚的页面上使用它。
产品组件
src/components/Products.vue
创建包含以下内容的 文件:
< template >
< div >
< div class = "py-28" >
< div class = "max-w-6xl mx-auto py-4 space-y-5" >
< div class = "flex" >
< div class = "flex-grow text-4xl font-extrabold" > Special Qualities For You</ div >
</ div >
< div class = "grid gap-20 grid-cols-1 md:grid-cols-2 lg:grid-cols-3 px-3" >
< div v-for = "(products, i) in fetchData" : key = "i" class = "rounded-lg shadow-xl" style = "" >
< router - link : to = "{ name: 'single-product', params: { id: products.id }}" >
< div class = " bg-white w-full flex justify-center items-center" >
< img : src = "products.thumbnail" alt = "" srcset = "" >
</ div >
< div class = "bg-purple-100 py-8 relative font-bold text-xl w-full flex flex-col justify-center px-6" >
< div class = "" > { { products . title } } </ div >
< div class = "" >
€ { { products . variants [ 0 ]. prices [ 0 ]. amount / 100 } }
</ div >
</ div >
</ router - link >
</ div >
</ div >
</ div >
</ div >
</ div >
</ template >
< script >
import axios from 'axios'
import { RouterLink } from 'vue-router';
export default ({
data (){
return {
fetchData :[]
}
},
mounted (){
// calling the fetchProducts method when the page has loaded
this . fetchProducts ();
},
methods :{
fetchProducts (){
axios . get ( ` ${ import . meta . env . VITE_baseUrl } /store/products` )
. then (( data ) => {
this . fetchData = data . data . products
}). catch ( err => console . log ( err . products ));
}
}
})
</ script >
Enter fullscreen mode
Exit fullscreen mode
产品组件用于使用 Medusa 的 API 获取产品。方法用于从 Medusa 服务器获取产品。请注意文件 中定义的 fetchProducts
用法 。 baseURL
.env
此外,Vue 路由器用于将每个选定的产品路由到您稍后添加的单个产品页面。
为路由页面创建 Vue.js 路由器文件
接下来要做的是创建一个路由文件来路由我们的页面。默认情况下,创建 vue.js 项目时总会生成一个路由文件。找到该 src/router/index.js
文件,并将其中的代码替换为以下内容:
import { createRouter , createWebHistory } from ' vue-router '
import HomeView from ' ../views/HomeView.vue '
import SingleProductView from ' ../views/SingleProductView.vue '
import ProductView from ' ../views/ProductView.vue '
const router = createRouter ({
history : createWebHistory ( import . meta . env . BASE_URL ),
routes : [
{
path : ' / ' ,
name : ' home ' ,
component : HomeView
},
{
path : ' /products ' ,
name : ' products ' ,
component : ProductView
},
{
path : ' /single-product/:id ' ,
name : ' single-product ' ,
component : SingleProductView
}
]
})
export default router
Enter fullscreen mode
Exit fullscreen mode
在上面的组件中,您指定了所有路由,包括路由路径、名称和组件。您添加的路由分别用于主页、产品页面和单个产品页面。
创建店面页面
在本部分中,您将为店面创建页面。在开始创建这些页面之前,请转到 src/App.vue
并将代码替换为以下内容:
< script setup >
import { RouterLink , RouterView } from 'vue-router'
import PageHeader from './components/PageHeader.vue'
</ script >
< template >
< header >
< page - header : productId = "products" />
</ header >
< RouterView @ addp = "addP($event)" />
< div class = "fixed top-12 bg-green-600 text-white z-50 border text-md uppercase shadow-lg py-1 px-4 rounded-lg transistion-all duration-700" : class = "notify" > item added successfully</ div >
</ template >
< script >
import axios from 'axios'
export default {
data (){
return {
products :[],
notify : ' -right-64 ' ,
cartId : '' ,
product_variant_id : null
}
},
mounted (){
this . checkCartID ()
},
methods :{
getCartID (){
axios . post ( ` ${ import . meta . env . VITE_baseUrl } /store/carts` ). then (( res ) => {
localStorage . cart_id = res . data . cart . id ;
});
},
checkCartID (){
this . cartId = localStorage . cart_id ;
if ( ! this . cartId ) {
this . getCartID ();
}
} ,
addP(data){
this . cartId = localStorage . cart_id ;
axios . post ( ` ${ import . meta . env . VITE_baseUrl } /store/carts/ ${ this . cartId } /line-items` , {
variant_id : data ,
quantity : 1 ,
})
. then (({ data }) => {
this . products . push ( data )
localStorage . cart = this . products
this . notify = ' right-3 '
var inter = setInterval (() => {
this . notify = ' -right-64 '
clearInterval ( inter )
}, 1000 )
})
}
}
}
</ script >
Enter fullscreen mode
Exit fullscreen mode
在这里,您导入标题组件,以便它出现在所有页面上。
您还添加了一些与购物车相关的方法。该 checkCartID
方法在页面加载时检查本地存储中是否存在购物车 ID,如果存在则调用该 getCartID
方法。该 getCartID
方法用于从 Medusa 服务器获取购物车及其商品。
该 addP
方法用于将产品添加到购物车。稍后将在“单品”页面上调用它。
您可以在文档 中了解有关 Medusa 购物车的更多信息 。
主页视图
src/views/HomeView.vue
创建包含以下内容的 文件:
< script setup >
import PageHeader from '../components/PageHeader.vue'
import Products from '../components/Products.vue'
import FooterComponent from '../components/FooterComponent.vue'
</ script >
< template >
< main >
< div class = "bg-purple-300 w-full" >
< div class = "" style = "height: 92vh" >
< div class = "max-w-6xl mx-auto h-full flex items-center" >
< div class = "grid gap-1 px-3 grid-cols-1 mt-8 md:grid-cols-5" >
< div class = "md:col-span-2 order-2 flex flex-col justify-center space-y-12" >
< div class = "space-y-5" >
< div class = "font-extrabold w-full text-6xl" >
Nothing But Qualities
</ div >
< div class = "text-lg leading-7 max-w-md" >
We sell quality Hoddies, Joggers, Shorts and lot more
</ div >
</ div >
< div >
< router - link : to = "{ name: 'products'}" >
< span class = 'w-fit cursor-pointer transistion-all duration-300 hover:text-purple-400 text-white px-3 py-3 bg-gradient-to-r from-purple-500 to-pink-500 rounded flex justify-center items-center' >
Explore More
</ span >
</ router - link >
</ div >
</ div >
< div class = "md:col-span-3 flex justify-center md:order-2" >
< img src = "/src/images/hoddie.png" class = "bottom-1 relative h-11/12" style = "" >
</ div >
</ div >
</ div >
</ div >
< div class = "flex justify-center bg-purple-300 py-4 pb-10 w-full" >
< div class = "h-14 rounded-2xl relative" style = "border: 1px solid black;padding:3px 6px 3px" >
< div class = "bg-black rounded-full relative top-10" style = "padding: 3px" ></ div >
</ div >
</ div >
</ div >
< products />
< footer - component />
</ main >
</ template >
< script >
export default {
mounted (){
this . handlePageScroll ()
},
methods :{
handlePageScroll (){
window . scrollTo ( 0 , this . scrollposition );
this . scrollposition = window . pageYOffset ;
}
}
}
</ script >
Enter fullscreen mode
Exit fullscreen mode
您导入此文件内的 Products
和 FooterComponent
组件并将它们显示在主页上。
产品页面浏览量
src/views/ProductView.vue
创建包含以下内容的 文件:
< script setup >
import PageHeader from '../components/PageHeader.vue'
import Products from '../components/Products.vue'
import FooterComponent from '../components/FooterComponent.vue'
</ script >
< template >
< main >
< products />
< footer - component />
</ main >
</ template >
Enter fullscreen mode
Exit fullscreen mode
您还可以导入此文件中的 Products
和 FooterComponent
组件,以便在产品列表页面中显示它们。
单个产品页面
src/views/SingleProductView.vue
创建包含以下内容的 文件:
< script setup >
import FooterComponent from '../components/FooterComponent.vue'
</ script >
< template >
< main ref = "addProd" >
< div class = 'py-20 px-4' >
< div class = 'text-white max-w-6xl mx-auto py-2' >
< div class = 'grid md:grid-cols-2 gap-20 grid-cols-1' >
< div class = '' >
< div class = "relative" >
< img : src = "imgArr[currentImg]" alt = "no image" />
< div class = "absolute overflow-x-scroll w-full bottom-0 right-0 p-4 flex flex-nowrap gap-4" >
< div v-for = "(er,i) in imgArr.length" : key = "i" class = "flex w-full flex-nowrap gap-4 rounded-lg" >
< div @ click = "currentImg = i" : title = "imgArr[i]" class = "w-16 h-24 flex-none" >
< div class = "h-full w-full rounded-lg cursor-pointer shadow-lg border overflow-hidden" >
< img : src = "imgArr[i]" alt = "" class = "h-full w-full" >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
< div class = '' >
< div class = 'flex md:flex-col flex-col space-y-7 justify-center' >
< div class = 'text-black space-y-3' >
< h2 class = 'font-bold text-xl text-black' > { { product . title } } </ h2 >
< p class = 'text-sm' > { { product . description } } </ p >
</ div >
< div class = 'space-y-3' >
< div class = 'font-bold text-md text-black' > Select Size</ div >
< div class = 'flex flex-row flex-wrap gap-4' >
< div v-for = "(size,i) in sizes" : key = "i" class = "" >
< div @ click = "currentSize = size ; currentPrice = priceList[i] ; variants_id = product.variants[i].id" : class = "currentSize == size ? 'border-purple-300 bg-purple-100':'border-gray-100' " contenteditable = "false" class = 'border-2 rounded-md cursor-pointer flex justify-center py-3 px-5' >
< span class = ' text-black text-sm' > { { size } } </ span >
</ div >
</ div >
</ div >
</ div >
< div >
< div class = 'flex flex-col space-y-3' >
< div >
< span class = 'text-gray-700 text-2xl font-san' > € { { currentPrice } } </ span >
</ div >
< div @ click = "addProduct()" class = 'bg-gray-900 cursor-pointer text-white w-full text-sm font-semibold py-3 flex justify-center cursor pointer hover:bg-white hover:border hover:border-gray-900 hover:text-black ' >
ADD TO CART
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
</ div >
< footer - component />
</ main >
</ template >
< script >
import axios from 'axios'
export default {
activated () {
window . scrollTo ( 0 , 0 );
},
data (){
return {
currentImg : 0 ,
imgArr :[],
productData :[],
product :[],
productId : '' ,
sizes :[],
currentSize : ' S ' ,
priceList :[],
currentPrice : '' ,
variants_id : 0
}
},
mounted (){
window . scrollTo ( 0 , 0 );
},
beforeMount (){
this . productId = this . $route . params . id
axios . get ( ` ${ import . meta . env . VITE_baseUrl } /store/products/ ${ this . productId } ` )
. then (( productData ) => {
this . product = productData . data . product ;
console . log ( this . product );
this . product . images . forEach ( data => {
this . imgArr . push ( data . url )
});
this . currentPrice = this . product . variants [ 0 ]. prices [ 0 ]. amount / 100
this . variants_id = this . product . variants [ 0 ]. id
this . product . variants . forEach ( data => {
this . sizes . push ( data . title )
this . priceList . push ( data . prices [ 0 ]. amount / 100 )
});
}). catch ( err => console . log ( err ));
},
methods :{
addProduct (){
this . $emit ( ' addP ' , this . variants_id )
}
}
}
</ script >
Enter fullscreen mode
Exit fullscreen mode
在上面的代码块中,您将使用其 ID 从 Medusa 服务器获取单个产品。然后,您将显示该产品的信息,包括其价格、尺寸和描述。
当点击“添加到购物车”按钮时,该 addProduct
方法将被执行。该方法调用 addP
在“Add to Cart”中定义的方法,并将 src/App.vue
所选的变体 ID 传递给该方法。
更改 Vue.js 端口
在文件中 vite.config.js
,将此代码片段添加到传递给的对象参数中 defineConfig
:
server : {
port : 8000
},
Enter fullscreen mode
Exit fullscreen mode
在上面的代码块中,您将 Vue.js 电商店面的端口更改为 8000
。这样可以避免 cors
向 Medusa 服务器发送请求时出现问题。
测试店面
您现在可以按照以下步骤测试您的 Vue.js 电子商务店面:
运行 Medusa 服务器:
medusa develop
Enter fullscreen mode
Exit fullscreen mode
运行 Vue.js 应用程序:
npm run dev
Enter fullscreen mode
Exit fullscreen mode
当您打开店面时 localhost:8000
,您会看到以下主页:
如果您向下滚动或单击导航栏中的产品项,您将看到从 Medusa 服务器填充的产品。
尝试点击任意产品,将打开一个新页面显示产品详细信息。
您可以点击“添加到购物车”按钮将产品添加到购物车。
下一步是什么?
在本教程中,您学习了如何在 Medusa 的帮助下创建 Vue.js 电商店面。该店面仅实现了产品列表和添加到购物车的功能,但您还可以添加更多功能。
请查看以下文档页面以获取有关如何继续前进的帮助:
如果您对 Medusa 有任何问题或疑问,请随时通过Discord 联系 Medusa 团队
鏂囩珷鏉ユ簮锛�https://dev.to/medusajs/how-i-created-a-vuejs-ecommerce-store-with-medusa-plf