vue结合elementplus走马灯实现商城系统首页轮播图
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
目录
写在前面
前段时间笔者不是专科毕业了么,当时写的毕业设计,是一个商城系统。原先的ui界面过于丑陋,于是就打算修改一下。
实现功能:在轮播图上显示商品分类、其他自定义内容。鼠标划过一级分类。显示子分类。子分类可点击进入搜索页面
预览
修改后:
修改前:
是不是好看多了?
明确实现步骤
- 准备轮播图:使用elementplus的走马灯
- 准备分类列表:一个垂直结构的列表
- 将分类列表显示到轮播图上:使用相对定位
- 鼠标划过分类列表,发送请求,并显示子分类列表:使用鼠标事件,变量结合v-show控制
- 鼠标划出分类列表和子分类列表,子分类列表关闭:鼠标事件,变量结合v-show
- 显示子分类和关闭子分类时,右侧盒子位置要保持不变:控制显示和不显示时的位置切换
我不会一步一步循序渐进的粘代码,因为步骤有点多,我相信读者也不想看又臭又长的代码,我想你只是想怎么快速读懂案例,并且能够快速找到不符合自己要求的部分,对其进行修改。
本文多次使用elementplus的layout布局
实现
先粘代码
代码(轮播图区域,不包含头部以及导航)
<template>
<div class="carousel-container">
<el-carousel height="500px" motion-blur arrow="always">
<el-carousel-item v-for="item in homeAdvList" :key="item">
<el-image :src="$img+item.pic" fit="fill" @click="goDetail(item.skuId)" style="height: 500px;width: 1440px"/>
</el-carousel-item>
</el-carousel>
<div class="overlay-content" @mouseleave="showCate=false" @click="showCate=false">
<el-row :gutter="10" style="height: 90%">
<el-col :offset="2" :span="4">
<el-card>
<el-space direction="vertical" alignment="flex-start" fill style="width: 100%">
<div v-for="item in categoryListData" :key="item.id">
<div @mouseover="getLevel1Category(item.id)" class="category_item_box">
<span style="font-size: 18px"> {{ item.name }}</span>
<div style="height: 20px;width: 20px">
<ArrowRight/>
</div>
</div>
</div>
</el-space>
</el-card>
</el-col>
<el-col :span="8" v-show="showCate">
<el-card>
<div v-for="item in Level1CategoryItem" style="padding: 10px 0" :key="item.id" class="category_item_box">
<span style="font-weight: 600;font-size: 16px">
{{ item.name }}
</span>
<br>
<div style="padding-left: 30px">
<span v-for="third in item.children" :key="third.id"
@click="goCommodityCategoryView(third.id,third.name)">
{{ third.name }}
<el-divider direction="vertical"/>
</span>
</div>
<hr>
</div>
</el-card>
</el-col>
<el-col :offset="showCate ? 4 : 12" :span="4">
<el-card style="height: 98%;">
<template #header>
<div class="card-header">
<span>系统公告</span>
</div>
</template>
<div>
xxx
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
<div style="padding-left: 150px">
<h2>最新上架</h2>
<el-divider/>
</div>
<div class="selected_father">
<div class="selected_class">
<el-scrollbar>
<div class="scrollbar-flex-content">
<div v-for="(item,index) in newSkuList" :key="item.id" class="scrollbar-demo-item" @click="toDetail(item.id)">
<el-image style="width: 150px; height: 150px" :src="$img+item.skuDefaultImg" fit="fill">
<template #error>
<div class="image-slot">
<el-icon>
<icon-picture/>
</el-icon>
</div>
</template>
</el-image>
<div v-if="index!==newSkuList.length-1">
<el-divider direction="vertical" style="height: 150px"/>
</div>
</div>
</div>
</el-scrollbar>
</div>
</div>
<div class="commodity_list_box_father">
<commodity-list></commodity-list>
</div>
</template>
<script setup>
import CommodityList from "@/components/home/CommodityList";
import {getCategoryByParent, getTreCategoryByParent} from "@/api/category";
import {getNewSkuListApi} from '@/api/goods'
import {onMounted, reactive, ref} from "vue";
import {useRouter} from "vue-router";
import {getUsingHomeAdvList} from "@/api";
let categoryListData = ref([])
let router = useRouter()
let pageInfo = reactive({
pageNum: 1,
pageSize: 5,
total: Number
})
let newSkuList = ref([])
let homeAdvList = ref([])
function getHomeAdv() {
getUsingHomeAdvList().then(res => {
homeAdvList.value = res.data
})
}
function goDetail(skuId) {
router.push({
path: '/detail',
query: {
skuId
}
})
}
onMounted(() => {
/*获取一级分类*/
getLevelCategoryList()
//获取首页轮播广澳
getHomeAdv()
//获取最新上架的商品
getNewSkuList()
})
/**
* 获取以一级分类
*/
function getLevelCategoryList() {
getCategoryByParent(0).then((res) => {
categoryListData.value = res.data
})
}
/*
获取最新上架sku
*/
function getNewSkuList() {
getNewSkuListApi(pageInfo).then(res => {
newSkuList.value = res.data.records
})
}
/**
* 前往商品详情
* @param skuId
*/
function toDetail(skuId) {
router.push({
path: '/detail',
query: {
skuId: skuId
}
})
}
//是否显示分类信息
let showCate = ref(false)
let Level1CategoryItem = ref([])//一级分类下的所有子分类
/**
* 前往该分类下的搜索页面
* @param categoryId
*/
function goCommodityCategoryView(categoryId, categoryName) {
router.push({
path: '/commodity-search',
query: {
categoryId,
categoryName
}
})
}
/**
* 获取选择的以及分类下的子分类(树结构)
* @param selectCategory
*/
function getLevel1Category(selectCategory) {
getTreCategoryByParent(selectCategory).then(res => {
Level1CategoryItem.value = res.data
}).finally(()=>{
showCate.value = true
})
}
</script>
<style scoped>
.carousel-container {
height: 500px;
position: relative; /* 确保子元素可以使用绝对定位 */
width: 100%; /* 根据需要调整 */
overflow: hidden; /* 如果需要隐藏超出轮播图的内容 */
}
.overlay-content {
position: absolute;
margin-top: 20px;
top: 0;/*此处可根据需要调整,但必须有 */
color: white; /* 根据背景色调整文本颜色 */
width: 100%; /* 根据需要调整宽度 */
z-index: 10; /* 确保内容在轮播图之上 */
}
.selected_father {
display: flex;
justify-content: center;
}
.category_item_box:hover {
background-color: #d3dce6;
color: #098CC0;
}
.category_item_box {
display: flex;
justify-content: space-between;
}
.commodity_list_box_father {
display: flex;
justify-content: center;
}
.selected_class {
width: 80%;
}
.scrollbar-flex-content {
display: flex;
}
.scrollbar-demo-item {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 4px;
padding: 5px;
}
.card-header {
background-color: orange;
}
</style>
布局解读
样式如下:
轮播图事项
指定高度,使用elemntplus提供的height属性指定大小;图片设置大小,并且使用fill值(即使图片不够宽高,也能自动拉伸填充指定的大小);$img是我后端服务器响应图片的接口地址,在此处可以更改为你图片路径
鼠标移除关闭子分类,不同情况右侧盒子的间距调整
由于这个class为overlay-content的div宽度范围比较大,导致鼠标横向滑动很难将shoCate的值转为false,所以此处可以添加一个点击事件,点击就关闭。这样如果你不想显示的时候随便点击就能关闭子分类的显示
鼠标悬停显示子分类
改进
上面的布局存在两个问题:
- 分类盒子过大,鼠标左右移动难以触发鼠标移出事件
- 显示子分类和不显示子分类时,右侧的盒子需要计算位置
总的来说就是布局不合理,这里我采用多次嵌套elmentplus的el-row和el-col解决。上面的代码因为有讲解,我就不删了。毕竟又不是什么大问题
改进后代码如下:
<template>
<div class="carousel-container">
<el-carousel height="500px" motion-blur arrow="always">
<el-carousel-item v-for="item in homeAdvList" :key="item">
<el-image :src="$img+item.pic" fit="fill" @click="goDetail(item.skuId)" style="height: 500px;width: 1440px"/>
</el-carousel-item>
</el-carousel>
<div class="overlay-content" @click="showCate=false">
<el-row :gutter="10" style="height: 90%">
<el-col :offset="2" :span="12" @mouseleave="showCate=false">
<el-row>
<el-col :span="8">
<el-card>
<el-space direction="vertical" alignment="flex-start" fill style="width: 100%">
<div v-for="item in categoryListData" :key="item.id">
<div @mouseover="getLevel1Category(item.id)" class="category_item_box">
<span style="font-size: 18px"> {{ item.name }}</span>
<div style="height: 20px;width: 20px">
<ArrowRight/>
</div>
</div>
</div>
</el-space>
</el-card>
</el-col>
<el-col :span="16" v-show="showCate">
<el-card>
<div v-for="item in Level1CategoryItem" style="padding: 10px 0" :key="item.id"
class="category_item_box">
<span style="font-weight: 600;font-size: 16px">
{{ item.name }}
</span>
<br>
<div style="padding-left: 30px">
<span v-for="third in item.children" :key="third.id"
@click="goCommodityCategoryView(third.id,third.name)">
{{ third.name }}
<el-divider direction="vertical"/>
</span>
</div>
<hr>
</div>
</el-card>
</el-col>
</el-row>
</el-col>
<el-col :offset="5" :span="4">
<el-card style="height: 98%;">
<template #header>
<div class="card-header">
<span>系统公告</span>
</div>
</template>
<div>
xxx
</div>
</el-card>
</el-col>
</el-row>
</div>
</div>
<div style="padding-left: 150px">
<h2>最新上架</h2>
<el-divider/>
</div>
<div class="selected_father">
<div class="selected_class">
<el-scrollbar>
<div class="scrollbar-flex-content">
<div v-for="(item,index) in newSkuList" :key="item.id" class="scrollbar-demo-item" @click="toDetail(item.id)">
<el-image style="width: 150px; height: 150px" :src="$img+item.skuDefaultImg" fit="fill">
<template #error>
<div class="image-slot">
<el-icon>
<icon-picture/>
</el-icon>
</div>
</template>
</el-image>
<div v-if="index!==newSkuList.length-1">
<el-divider direction="vertical" style="height: 150px"/>
</div>
</div>
</div>
</el-scrollbar>
</div>
</div>
<div class="commodity_list_box_father">
<commodity-list></commodity-list>
</div>
</template>
<script setup>
import CommodityList from "@/components/home/CommodityList";
import {getCategoryByParent, getTreCategoryByParent} from "@/api/category";
import {getNewSkuListApi} from '@/api/goods'
import {onMounted, reactive, ref} from "vue";
import {useRouter} from "vue-router";
import {getUsingHomeAdvList} from "@/api";
let categoryListData = ref([])
let router = useRouter()
let pageInfo = reactive({
pageNum: 1,
pageSize: 5,
total: Number
})
let newSkuList = ref([])
let homeAdvList = ref([])
function getHomeAdv() {
getUsingHomeAdvList().then(res => {
homeAdvList.value = res.data
})
}
function goDetail(skuId) {
router.push({
path: '/detail',
query: {
skuId
}
})
}
onMounted(() => {
/*获取一级分类*/
getLevelCategoryList()
//获取首页轮播广澳
getHomeAdv()
//获取最新上架的商品
getNewSkuList()
})
/**
* 获取以一级分类
*/
function getLevelCategoryList() {
getCategoryByParent(0).then((res) => {
categoryListData.value = res.data
})
}
/*
获取最新上架sku
*/
function getNewSkuList() {
getNewSkuListApi(pageInfo).then(res => {
newSkuList.value = res.data.records
})
}
/**
* 前往商品详情
* @param skuId
*/
function toDetail(skuId) {
router.push({
path: '/detail',
query: {
skuId: skuId
}
})
}
//是否显示分类信息
let showCate = ref(false)
let Level1CategoryItem = ref([])//一级分类下的所有子分类
/**
* 前往该分类下的搜索页面
* @param categoryId
*/
function goCommodityCategoryView(categoryId, categoryName) {
router.push({
path: '/home/commodity-search',
query: {
categoryId,
categoryName
}
})
}
/**
* 获取选择的以及分类下的子分类(树结构)
* @param selectCategory
*/
function getLevel1Category(selectCategory) {
getTreCategoryByParent(selectCategory).then(res => {
Level1CategoryItem.value = res.data
}).finally(() => {
showCate.value = true
})
}
</script>
<style scoped>
.carousel-container {
height: 500px;
position: relative; /* 确保子元素可以使用绝对定位 */
width: 100%; /* 根据需要调整 */
overflow: hidden; /* 如果需要隐藏超出轮播图的内容 */
}
.overlay-content {
position: absolute;
margin-top: 20px;
top: 0; /*此处可根据需要调整,但必须有 */
color: white; /* 根据背景色调整文本颜色 */
width: 100%; /* 根据需要调整宽度 */
z-index: 10; /* 确保内容在轮播图之上 */
}
.selected_father {
display: flex;
justify-content: center;
}
.category_item_box:hover {
background-color: #d3dce6;
color: #098CC0;
}
.category_item_box {
display: flex;
justify-content: space-between;
}
.commodity_list_box_father {
display: flex;
justify-content: center;
}
.selected_class {
width: 80%;
}
.scrollbar-flex-content {
display: flex;
}
.scrollbar-demo-item {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
border-radius: 4px;
padding: 5px;
}
.card-header {
background-color: orange;
}
</style>
源码地址:
找到
GitHub 加速计划 / eleme / element
54.07 K
14.63 K
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:3 个月前 )
c345bb45
7 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 8 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)