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

一、前言

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-searchshape="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.newGoodsesnewGoods.hots = result.data.data.hotGoodsesnewGoods.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.mzph.cn/diannao/34519.shtml

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

相关文章

针对AIGC检测的鲁棒性测试——常见攻击手段汇总

前言&#xff1a;这篇文章来总结一下针对AIGC检测的常见攻击手段&#xff0c;选取的研究工作均出自近5年AIGC检测相关文章。&#xff08;论文被拒了需要补实验&#xff0c;先来看看别人怎么做的……&#xff09; 2019 WIFS Detecting and Simulating Artifacts in GAN Fake Ima…

JavaScript的学习之事件的简介

目录 一、事件是什么 二、如何处理事件 一、事件是什么 定义&#xff1a;事件就是浏览器和用户之间的交互行为。 例如&#xff1a;点击按钮、鼠标移动、关闭窗口等。 二、如何处理事件 我们可以在对应的事件属性中设置一些JS行为&#xff0c;当事件触发的时候会将这些代码执行…

35岁,是终点?还是拐点?

35岁&#xff0c;是终点还是拐点&#xff0c;取决于我们对生活和事业的态度、目标以及行动。这个年龄可以看作是一个重要的转折点&#xff0c;具有多重意义和可能性。 很多人在35岁时&#xff0c;已经在自己的职业生涯中建立了一定的基础&#xff0c;可能达到了管理层或专家级别…

Charles抓包工具系列文章(二)-- Repeat 回放http请求

一、什么是http请求回放 当我们对客户端进行抓包&#xff0c;经常会想要重试http请求&#xff0c;或者改写原有部分进行重新请求&#xff0c;都需要用到回放http请求。 还有一种场景是压力测试&#xff0c;对一个请求进行重复请求多少次&#xff0c;并加上适当的并发度。 这里…

WebStorm 配置 PlantUML

1. 安装 PlantUML 插件 在 WebStorm 插件市场搜索 PlantUML Integration 并安装&#xff0c;重启 WebStorm 使插件生效。 2. 安装 Graphviz PlantUML 需要 Graphviz 来生成图形。使用 Homebrew 安装 Graphviz&#xff1a; 打开终端&#xff08;Terminal&#xff09;。确保你…

C语言小例程28/100

题目&#xff1a;利用递归方法求5!。 程序分析&#xff1a;递归公式&#xff1a;fnfn_1*4! #include <stdio.h>int main() {int i;int fact(int);for(i0;i<6;i){printf("%d!%d\n",i,fact(i));} } int fact(int j) {int sum;if(j0){sum1;} else {sumj*fac…

闪迪sd卡视频格式化数据恢复方法,你了解吗

咨询&#xff1a;“我不小心将闪迪SD卡格式化了&#xff0c;里面的重要视频文件全都不见了。我感到非常焦虑&#xff0c;因为这些视频对我来说意义非凡。现在急需找到方法来恢复&#xff01;&#xff01;” 在数字时代&#xff0c;SD卡已成为我们日常生活中不可或缺的数据存储设…

python中数据的作用域

一、命名空间 在 Python 中&#xff0c;命名空间是一个系统&#xff0c;它用于确保名字的唯一性&#xff0c;并防止命名冲突。命名空间是一个存储变量名称&#xff08;或者更广泛地说&#xff0c;标识符&#xff09;与对象之间映射的抽象概念。每个变量名你在程序中创建&#x…

msvcp120.dll丢失怎么办,找不到msvcp120.dll的多种解决方法

最近&#xff0c;我在运行一个程序时遇到了一个错误&#xff0c;系统提示找不到msvcp120.dll文件&#xff0c;无法继续执行代码。这让我感到非常困扰&#xff0c;因为这个问题导致我无法正常运行这个程序。经过一番搜索和尝试&#xff0c;我找到了几种修复这个问题的方法&#…

如何开发、使用 Starter

开发 第一步&#xff1a;创建starter工程hello-spring-boot-starter并配置pom.xml文件 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchem…

SpringBoot优点达项目实战:项目初始化(一)

SpringBoot优点达项目实战&#xff1a;项目初始化&#xff08;一&#xff09; 文章目录 SpringBoot优点达项目实战&#xff1a;项目初始化&#xff08;一&#xff09;1、项目介绍2、项目搭建3、依赖导入4、数据准备 1、项目介绍 技术框架 SpringbootmybatisPlusvueknife 2、项目…

创建App

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在Django项目中&#xff0c;推荐使用App来完成不同模块的任务&#xff0c;通过执行如下命令可以启用一个应用程序。 python manage.py startapp app…

RT-Thread的Finsh实现学习

学习原因 工作中&#xff0c;使用同事开发的调试软件&#xff0c;输入参数打印的函数名就可以打印参数&#xff0c;但看不到代码实现&#xff0c;只能用自己微薄的知识积累去猜一下&#xff0c;之前尝试过&#xff0c;专门写一个函数&#xff0c;去解析编译生成的map文件&#…

名侦探李先生第一话:谁是真正的凶手(只出现一次的数字相关题解(力扣)+位操作符回忆)

引子&#xff1a;我们在之前的案子中破解过基础的单身狗问题&#xff0c;那面对更有挑战的案子&#xff0c;且看李先生如何破局&#xff0c;那下凶手&#xff01; 复习&#xff1a; 1&#xff0c;位操作符&#xff1a; 正整数原&#xff0c;反&#xff0c;补码都相同 首位是…

RocketMQ如何添加JVM监控

这里是小奏,觉得文章不错可以关注公众号小奏技术 JVM监控选型 本次JVM监控我们采用prometheus官方提供的jmx_exporter来实现 RocketMQJVM开发 整体目录 1. 新增agent目录 我们在distribution目录新增一个agent模块&#xff0c;然后添加两个文件 jmx_prometheus_javaagent-…

NtripShare2024年第二季度主要技术进展

NtripShare Cloud GNSS解算云平台方面 1、解算引擎增加根据卫星多路径效应自动剔除卫星的算法。 2、解算引擎增加解算时间段限制&#xff08;发现贵州某地在晚12点周期性效果变差&#xff09;。 3、增加2000坐标至地方坐标系转换的支持(七参数、四参数、TGO高程拟合&#x…

[数据集][目标检测]棉花检测数据集VOC+YOLO格式389张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;389 标注数量(xml文件个数)&#xff1a;389 标注数量(txt文件个数)&#xff1a;389 标注类别…

办理北京公司注册地址异常变更要求和流程

在北京注册公司时选择注册地址是非常重要的一环&#xff0c;注册地址不仅体现在营业执照上&#xff0c;在网上也有公示信息&#xff0c;一般选用的是商用地址和商住两用地址&#xff0c;在公司经营过程中&#xff0c;因为经营需要变更注册地址&#xff0c;也要依法变更&#xf…

低价可转债崩盘,发生了什么?

下跌不在于“出库”&#xff0c;甚至不在于“风险”。问题更多在于交易层面&#xff0c;何时能积聚更多的左侧资金并成功过渡至右侧。 低价券怎么了&#xff1f; 如果说6月初主要是小微盘品种的退市风险&#xff0c;后来是一些评级下调的品种&#xff0c;到本周&#xff0c;已…

ONLYOFFICE 桌面编辑器 8.1重磅来袭:全新功能提升您的办公效率

文章目录 前言ONLYOFFICE 桌面编辑器8.1一、PDF编辑&#xff1a;告别“头痛”时刻二、幻灯片版式&#xff1a;秒变“设计大师”三、无缝切换&#xff1a;办公界的“快速通道”四、语言支持&#xff1a;全球通吃的“翻译官”五、 隐藏“连接到云”板块&#xff1a;摆脱“云”的束…