使用vant4+vue3制作电商购物网站

news2024/10/6 6:41:23

一、前言

1.本项目基于vant4+vue3构建,默认友友们已具备相关知识,如不具备,请友友们先去了解相关该概念

2.项目数据来源于开源框架 新峰商城 在此指出

3.此项目目的在于帮助友友们了解基本的用法,没有涉及太多的逻辑操作。

二、项目介绍

首页

分类

我的

三、项目搭建

大家可以看看项目所需的依赖,具体的安装命令如下

axios

npm install axios --save

less(为了书写样式方便,不需要强制安装)

npm install less --save

mockjs(使用mockjs制造假数据)

npm install mockjs --save

vant(可以去官网看看组件的使用用法)

npm i vant

vue-router(必须要的哈,进行页面切换的)

npm install vue-router

安装为项目所需的依赖,我们需要将需要的依赖引入我们的项目中

在main.js中引入并使用安装好的vant

创建路由并加载到main.js

路由的配置

注意:路由文件所需要的home、user、cag组件自己先定义好,然后引入到路由文件中,大家也可以使用懒加载的方式,具体组件的创建就不演示了。

四、页面制作

在配置完路由之后,思考我们的配置的路由是做什么的。通常为了页面的切换,我们会需要一个固定在顶部的导航条,我们称之为tabbar,且所有的页面都能看到这个导航条

首页显示

路由配置结束,需要将其显示出来,路由出口配置在app.html页面

在本项目中,我将首页重定向到home页面,所有接下来的所有操作,我们去到home页面

这是home页面的结构,包括搜索框、轮播图、商品分类、商品显示,顶部导航,有经验的小伙伴可以看看view文件夹和components文件夹,这里我将具体的页面放在view下,其余组件拆分放到components

具体显示效果如下

现在我们拆分这个页面

搜索框

代码

<template>
    <van-sticky>
        <van-search
          shape="round"
          background="#1baeae"
          placeholder="请输入搜索关键词"
        >
 
        </van-search>
    </van-sticky>

</template>

van-sticky为黏性布局,也就是鼠标向下滑动,搜索框会固定在顶部

轮播图(swiper)

代码

<template>
    <van-swipe :autoplay="3000" lazy-render>
      <van-swipe-item v-for="(item,index) in newGoods.carousels" :key="index">
        <img :src="item.carouselUrl" />
  </van-swipe-item>
</van-swipe>
</template>
<script setup>
    import {onMounted,reactive} from "vue"
    import request from "../mock/request.js"
    const newGoods = reactive(
        {
            carousels:[]
        }
    )
    onMounted(async() =>{
        let result = await request({
          url:'/mock/getGoods',
          method:'get'
      })
      if(result.data.code === 200){
          newGoods.carousels = result.data.data.carousels
      }
     
    })
</script>
<style type="text/css" media="all" scoped>
    img{
        width: 100%;
        height: 200px;
    }
</style>

这里大家看看mock中我们写的假的json数据

{
     "carousels": [
      {
        "carouselUrl": "https://res.vmallres.com/uomcdn/CN/cms/2024-05/6580fa613c574939a84e0a04e288292b.jpg",
        "redirectUrl": "https://juejin.im/book/6844733826191589390"
      },
      {
        "carouselUrl": "https://res.vmallres.com/uomcdn/CN/cms/202405/240051cba47c47d384142a253d50cb6d.png",
        "redirectUrl": "https://juejin.im/book/6844733826191589390"
      },
      {
        "carouselUrl": "https://res.vmallres.com/uomcdn/CN/cms/202406/c16311df062d43c49f9e692728b5efd4.jpg",
        "redirectUrl": "https://juejin.im/book/6844733826191589390"
      },
      {
        "carouselUrl": "https://res.vmallres.com/uomcdn/CN/cms/2024-05/1e56a1ce74b8447baaf08b87eaf007ec.jpg",
        "redirectUrl": "https://juejin.im/book/6844733826191589390"
      }
      
    ]
}

看看mockserver.js文件,如果小伙伴写过node的话,这里应该很好理解

这里写了三个接口,对于的三个页面数据,轮播图中用的数据都在goods中,在request文件中,只是简单的对超时做了限制

此项目不需要我们我们二次封装axios

了解完这些前置知识和后,我们在认真关注下我们的swiper组件中的内容

认真看完上面教程,给位友友们应该可以将轮播图正确显示出来了

商品分类

代码

<template>
    <van-grid clickable   :column-num="5">
      <van-grid-item to="/cag" v-for="(value,index) in categoryList.list" :key="index"  :text="value.name">
          <van-image :src="value.imgUrl"></van-image>
          <span>{{value.name}}</span>
      </van-grid-item>
    </van-grid>

</template>
<script setup>
    import {onMounted,reactive} from "vue"
    import request from "../mock/request.js"
    const categoryList = reactive(
        {
            list:[]
        }
    )
    onMounted(async() =>{
        let result = await request({
          url:'/mock/getCategoryList',
          method:'get'
      })
      if(result.data.code === 200){
          categoryList.list = result.data.data
      }
      
    })
</script>
<style type="text/css" media="all" >
    .van-image__img{
        width: 50px !important;
        height: 50px !important;
    }
    span{
        font-size: 20px !important;
    }
</style>

我们看看这个页面的结构

mock中的数据

商品页面

代码

<template>
    <header class="good-header">新品上线</header>
    <div class="good-box" >
          <div class="good-item" v-for="item in newGoods.newGoods" :key="item.goodsId" @click="goToDetail(item)">
            <img :src="item.goodsCoverImg" alt="">
            <div class="good-desc">
              <div class="title">{{ item.goodsName }}</div>
              <div class="price">¥ {{ item.sellingPrice }}</div>
            </div>
          </div>
    </div>
   
      
</template>
<script setup>
    import { useRouter } from 'vue-router'
    import {onMounted,reactive} from "vue"
    import request from "../mock/request.js"
    const router = useRouter();
    const newGoods = reactive(
        {
            newGoods:[],
            hots: [],
            recommends: [],
        }
    )
    onMounted(async() =>{
        let result = await request({
          url:'/mock/getGoods',
          method:'get'
      })
      if(result.data.code === 200){
          newGoods.newGoods = result.data.data.newGoodses
          newGoods.hots = result.data.data.hotGoodses
          newGoods.recommends = result.data.data.recommendGoodses
      }
     
    })
    const goToDetail = (item) => {
      router.push({ path: `/product/${item.goodsId}` })
    }
</script>
<style  scoped>

    .good-header {
      background: #f9f9f9;
      height: 50px;
      line-height: 50px;
      text-align: center;
      color: #1baeae;
      font-size: 25px;
      font-weight: 500;
    }
   .good-box {
      display: flex;
      justify-content: flex-start;
      flex-wrap: wrap;
      
    }
   .good-item {
        box-sizing: border-box;
        width: 50%;
        border-bottom: 1PX solid #e9e9e9;
        padding: 10px 10px;
        
    }
    .good-item:nth-child(2n + 1) {
          border-right: 1PX solid #e9e9e9;
    }
    img {
      display: block;
      width: 120px;
      margin: 0 auto;
    }
    .good-desc {
      text-align: center;
      font-size: 20px;
      padding: 10px 0;
     
    }
      .title {
        color: #222333;
      }
      .price {
        color:#1baeae;
      } 
      
</style>

代码解释

点击挑转到商品详情

详情页面也是一致的,大家看情况编写。由于涉及到后续的购物车,所有我没有继续往下写了

底部导航

代码

<template>
    <van-tabbar v-model="active" class="bar"> 
      <van-tabbar-item icon="home-o" to="/home">首页</van-tabbar-item>
      <van-tabbar-item icon="search" to="/cag">分类</van-tabbar-item>
      <van-tabbar-item icon="friends-o" to="/user">个人</van-tabbar-item>
    </van-tabbar>
</template>

<script setup>
import { ref} from "vue"
    const active = ref('home');
</script>
<style type="text/css" >
    .bar{
        margin-top: 40px !important;
        
    }
    .van-tabbar-item{
        font-size: 16px !important;
    }
</style>

这里的代码就不做解释了,相信大家都能看懂

将所需要要的组件引入即可

分类页面

分类页面比较简单,经过首页一节的铺垫,现在我们将节奏快点

页面分为上中下三层。上层为搜索框;中间左侧为侧边栏,右边为商品;下层为导航条

代码

<template>
    <TabNav></TabNav>
    <div class="container">
        <SliderNav></SliderNav>
        <CagGoods></CagGoods>
    </div>
    <div style="width:100%;height:40px"></div>
    <Tabbar></Tabbar>
</template>
<script setup>
    import Tabbar from "../components/Tabbar.vue"
    import TabNav from "../components/TabNav.vue"
    import SliderNav from "../components/SliderNav.vue"
    import CagGoods from "../components/CagGoods.vue"
    
</script>
<style scoped>
    .container{
        display: flex;
        flex-direction: row;
    }
    .container .van-sidebar  {
        flex: 2;
    }
    .container .van-grid{
        flex: 10;
    }
</style>

这里贴出的代码是为了方便大家布局使用的

顶部导航

侧边栏

右侧goods

我的

<template>
    <div class="user">
        <Card></Card>
        <div class="box">
            <van-icon name="setting-o" class="setting"/>
            <span>设置</span>
        </div>
        <div class="box1">
           <van-icon name="service-o" class="service" ></van-icon>
            <span>联系客服</span>
        </div>
       
        <MyOrder></MyOrder>
        <MySerive></MySerive>
    </div>
    <Tabbar></Tabbar>
</template>
<script setup>
    import Tabbar from "../components/Tabbar.vue"
    import Card from "../components/Card.vue"
    import MyOrder from "../components/MyOrder.vue"
    import MySerive from "../components/MySerive.vue"
    
</script>
<style >
    .user{
        position: relative;
    }
    .van-card__title {
        font-size: 20px !important;
        margin-top: 10px;
        height: 30px !important;
        line-height: 30px;
    }
   
   
    .box{
        display: flex;
        position: absolute;
        top: 10px;
        right: 20px;
        font-size: 25px;
        flex-direction: column;
    }
     .box1{
        display: flex;
        position: absolute;
        justify-content:center;
        align-content: center;
        top: 10px;
        right: 80px;
        font-size: 25px;
        flex-direction: column;
    }
    .service{
        text-align: center;
    }
    span{
        font-size: 12px;
    }
   
</style>

MyOrder

<template>
    <div class="temp">
        <div class="top">
            <span class="order">我的订单</span>
            <span class="all">全部></span>
        </div>
        <div class="content">
            <div>
                 <van-icon name="shop-o" />
                <span>待付款</span>
            </div>
             <div>
                <van-icon name="gift-card-o" />
                <span>待发货</span>
            </div>
             <div>
                <van-icon name="setting-o" class="setting"/>
                <span>待收货</span>
            </div>
             <div>
                <van-icon name="chat-o" />
                <span>待评价</span>
            </div>
             <div>
                 <van-icon name="balance-o" />
                <span>退款/售后</span>
            </div>
        </div>
    </div>
</template>
<script>
    
</script>
<style scoped>
    *{
        margin: 0;
        padding: 0;
     
    }
    .temp{
        display: flex;
        flex-direction: column;
        margin-top: 5px;
        transition: 0.3s;
        margin: 10px;
        padding: 10px;
        border-radius: 5px;
        background: #1baeae;
        box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
        overflow: hidden;
    }
     .temp:hover{
         box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2);
     }
    .top{
        display: flex;
        justify-content: space-between;
        align-content: center;
    }
    .order{
        font-size: 20px;
    }
    .all{
        margin-right: 20px;
    }
    .content{
        display: flex;
        flex-direction: row;
        justify-content: center;
    }
    .content div{
        margin-top: 10px;
        margin-left: 20px;
        display: flex;
        flex-direction: column;
        flex: 1;
        text-align: center;
    }
    .content div span{
        margin-top: 5px;
    }
</style>

这里大家掌握flex布局即可写出

MySerive

这个页面其实也是一样的,只是一个横向,一个纵向

写在最后

到这里就算写完了,希望各位友友们可以自己多加思考,清楚掌握。

同时也请大家多多点赞支持

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1857871.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

医院信息管理系统的设计与实现

你好&#xff0c;我是信息技术领域的研究者。如果你对医院信息管理有兴趣&#xff0c;欢迎交流。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; Java技术&#xff0c;SpringBoot框架&#xff0c;B/S模式 工具&#xff1a; MyEclipse&#xff0c;M…

测试卡无法仪表注册问题分析

1、问题描述 00101测试卡无法注册LTE网络&#xff0c;modemlog中发现终端未发起Attach请求&#xff0c;对比正常注册非正常注册的版本&#xff0c;发现正常的多出了ims apn。可以通过ATCGDCONT?来查询modem APN参数。 2、问题分析 目前Modem是一套&#xff0c;没有相关修改。因…

主食冻干喂猫是真对猫好吗?这些选购指南学会了是真不踩雷!

随着科学养猫知识的普及&#xff0c;主食冻干喂养越来越受到养猫人的青睐。主食冻干不仅符合猫咪的饮食天性&#xff0c;还能提供均衡的营养&#xff0c;有助于维护猫咪的口腔和消化系统健康。虽然许多猫主人看到了主食冻干喂养的诸多好处&#xff0c;但在选择适合的主食冻干产…

6.19长难句打卡

The Flatiron School, where people pay to learn programming, started as one of the many coding bootcamps that’s become popular for adults looking for a career change. 人们在Flatiron学校里花钱学习编程&#xff0c;且Flatiron学校也成为在寻求职业变化的成年人之中…

一文读懂交换机MAC地址表:五大关键点,图解21步

HCIA 新班开课了华为HCIA课程介绍苏州面授班 | 全国直播班循环开班&#xff0c;免费重学前言 什么是MAC地址表?MAC地址表有什么作用&#xff1f;MAC地址表里面包含了哪些要素&#xff1f;今天带你好好唠唠。 我们以一个案例为例&#xff1a; 如上图&#xff1a;PC1和PC2通…

vscode linux项目插件global扩展安装

vscode经常用来编辑linux系统下的项目&#xff1b;但是经常出现一些小问题&#xff1b;例如代码导航&#xff1a; 有时想要跳转到函数定义时会提示&#xff1a;未找到xxx的任何定义&#xff1b;更奇怪的是有的函数可以跳转有的函数不能跳转&#xff1b;理论上来说C/C插件已经具…

脑洞大开!用大模型开卡车,还融了2亿美元

物理生成式AI驾驶平台Waabi在官网宣布获得2亿美元&#xff0c;本次由英伟达&#xff08;NVIDIA&#xff09;、沃尔沃、保时捷、Uber、Khosla等全球知名企业投资。 Waabi仅成立3年便获得4级自主驾驶权限&#xff0c;主要是借助了ChatGPT等生成式AI风口&#xff0c;将其融合在自…

AI风险管理新利器:SAIF CHECK利用Meta Llama 3保障合规与安全

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

设计软件有哪些?贴图插件篇(2),渲染100邀请码1a12

这次我们继续介绍一些贴图插件。 1、Texporter Texporter是3ds Max的一个插件&#xff0c;用于快速导出贴图。它允许用户一次性导出多个贴图通道&#xff0c;如漫反射、法线、置换等&#xff0c;以各种格式&#xff0c;如TGA、BMP、JPEG等。Texporter提供了简单易用的界面和灵…

ctr/cvr预估之WideDeep模型

ctr/cvr预估之Wide&Deep模型 在探索点击率&#xff08;CTR&#xff09;和转化率&#xff08;CVR&#xff09;预估的领域中&#xff0c;我们始终追求的是一种既能捕获数据中的线性关系&#xff0c;又能发现复杂模式的模型。因子分解机&#xff08;Factorization Machines, …

6.21长难句打卡

Students also benefit from learning something about coding before they get to college, where introductory computer-science classes are packed to the brim, which can drive the less-experienced or -determined students away. 1.brim v.充满 n.边缘 在上大学之前…

Nature重磅:揭开睡眠不足为什么会损害记忆力

我们的记忆力会在睡眠期间得到增强&#xff0c;海马体是大脑的记忆中心&#xff0c;而海马体尖波涟漪&#xff08;sharp-wave ripple&#xff0c;SWR&#xff09;期间觉醒体验的激活和重放被认为是记忆力得到增强的关键。睡眠不足会损害记忆力&#xff0c;然而&#xff0c;我们…

四川赤橙宏海商务信息咨询有限公司电商服务正规吗?

在数字时代的浪潮下&#xff0c;电商行业正以前所未有的速度蓬勃发展。而在这个风起云涌的电商江湖中&#xff0c;四川赤橙宏海商务信息咨询有限公司以其独特的抖音电商服务策略&#xff0c;迅速崭露头角&#xff0c;成为业界翘楚。今天&#xff0c;我们就来聊聊这家公司如何凭…

matplotlib赛博朋克绘图风格介绍(mplcyberpunk)

matplotlib绘图风格 mplcyberpunk mplcyberpunk是一个matplotlib绘图风格的扩展包,利用这个python包,可以轻易的创建出精美的赛博朋克风格图表,方法介绍: import matplotlib.pyplot as plt import mplcyberpunkplt.style.use("cyberpunk")add_glow_effects #使图形…

SQL Server - ROLLUP、GROUPING、CUBE、GROUPING SET

文章目录 SQL Server - ROLLUP、GROUPING、CUBE、GROUPING SETROLLUP函数GROUPING函数GROUPING SET函数CUBE函数网上例子 写在前面&#xff1a;如果我们想要对分组之后的数据进行类似小计的计算&#xff0c;那么就需要使用到下面的函数 SQL Server - ROLLUP、GROUPING、CUBE、G…

解决bat脚本输出中文乱码

2024.06.24 测试&#xff0c;使用方法&#xff08;1&#xff09;已解决问题。 原文连接 一、乱码原因 Windows的cmd.exe默认编码格式为ANSI。简体中文版的Windows, 其ANSI对应微软Codepage为cp936 如果你的bat文件是UTF-8编码的, 或者是是其他Codepage下创建的, 当bat文件编码…

C语言基础——函数(2)

ʕ • ᴥ • ʔ づ♡ど &#x1f389; 欢迎点赞支持&#x1f389; 文章目录 前言 一、return语句 二、数组做函数参数 三、嵌套调用和链式访问 3.1 嵌套调用 3.2 链式访问 四、函数声明和定义 4.1 单个文件 4.2 多个文件 总结 前言 大家好啊&#xff0c;继我们上一…

快速鲁棒的 ICP (Fast and Robust Iterative Closest Point)

迭代最近点&#xff08;Iterative Closet Point&#xff0c;ICP&#xff09;算法及其变体是两个点集之间刚性配准的基本技术&#xff0c;在机器人技术和三维重建等领域有着广泛的应用。ICP的主要缺点是&#xff1a;收敛速度慢&#xff0c;以及对异常值、缺失数据和部分重叠的敏…

【强化学习的数学原理】课程笔记--1(基本概念,贝尔曼公式)

目录 基本概念State, Action, State transitionPolicy, Reward, Trajectory, Discount ReturnEpisodeMarkov decision process 贝尔曼公式推导确定形式的贝尔曼公式推导一般形式的贝尔曼公式State ValueAction Value 一些例子贝尔曼公式的 Matric-vector form贝尔曼公式的解析解…

图片多级缓存加载流程

图片多级缓存加载流程通常包括三个主要级别&#xff1a;内存缓存、本地缓存和网络缓存。以下是详细的加载流程&#xff1a; 1. 内存缓存&#xff08;一级缓存&#xff09; 流程&#xff1a; 当应用需要加载一张图片时&#xff0c;首先会检查内存缓存中是否存在该图片。 如果…