如何使用 Node.js 后端 Medusa 构建 Vue.js 电子商务商店

2025-06-09

如何使用 Node.js 后端构建 Vue.js 电子商务商店

美杜莎

电子商务并非易事。除了在前端打造出色的客户体验外,您还需要正确的设置来处理所有购物车、客户和订单数据、产品信息等……

在本教程中,您将了解到如何做到这一点!

在本教程中,您将了解打造卓越电商体验所需的必要前提条件。Vue.js是前端框架的绝佳选择,因为它是开源的,采用基于组件的架构,并且具有响应式特性

对于后端,您将学习如何使用Medusa,这是一个开源 Node.js 商务引擎,它附带所有必要的电子商务功能,包括易于导航的管理系统。

此 Vue.js 项目的完整代码位于此 GitHub 仓库。以下是最终结果的简要预览。

图片描述

什么是 Vue.js

Vue.js是一个开源的渐进式 JavaScript 框架。它可以用于构建各种类型的应用程序,包括网站、移动应用程序和桌面应用程序。这可以通过将 Vue.js 与其他平台(例如 Electron 或 Ionic)结合使用来实现。

Vue.js 自发布以来,凭借其众多优势而人气飙升。它易于学习和使用,拥有简洁的文档和流畅的学习曲线。此外,它体积小巧,采用响应式系统,并采用基于组件的可复用架构。

美杜莎是什么

GitHub 徽标 medusajs /美杜莎

全球最灵活的商业平台。

美杜莎标志

美杜莎

数字商务的基石

Medusa 是在 MIT 许可下发布的。 欢迎 PR!

关注@medusajs Discord聊天

入门

访问文档来设置 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,请按照以下步骤操作。

  1. 克隆 Medusa Admin 存储库:
git clone https://github.com/medusajs/admin medusa-admin
cd medusa-admin
Enter fullscreen mode Exit fullscreen mode
  1. 运行以下命令来安装所有必要的依赖项:
npm install
Enter fullscreen mode Exit fullscreen mode
  1. 测试一下:
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.jspostcss.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。.envvuejs-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 项目创建组件

在本部分中,您将创建诸如HeaderFooterProducts等组件。这些组件将用于店面的不同页面。

一些组件会使用图片来实现更好的店面设计。您可以在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="">
                                &euro; {{ 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

您导入此文件内的ProductsFooterComponent组件并将它们显示在主页上。

产品页面浏览量

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

您还可以导入此文件中的ProductsFooterComponent组件,以便在产品列表页面中显示它们。

单个产品页面

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'>&euro; {{ 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 电子商务店面:

  1. 运行 Medusa 服务器:
medusa develop
Enter fullscreen mode Exit fullscreen mode
  1. 运行 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
PREV
开源电商——Medusa 与 Shopify 的对比
NEXT
阵列折叠能做什么?