简介
在项目开发过程中遇到了一个实现淘宝侧边栏的功能,这个功能想了半天,最终还是做出来了,
其实也没那么复杂,主要是数据解构设计的合理即可,效果:鼠标移动到不同的列表项右边显示不同的效果 技术栈:nuxt.js
具体如下效果如下所示
实现原理
其实,实现原理也很简单,一边是左边列表项,一边是展示区 用两个容器包裹即可
鼠标移到左边列表项得到其对应的唯一type类型,拿到type类型展示数据即可,逻辑就这么简单
HTML代码
<div class="m-menu">
<dl class="nav" @mouseleave="mouseleave">
<dt>全部分类</dt>
<dd v-for="(item, index1) in menu" :key="index1" @mouseenter="enter">
<i :class="item.type" />
{{item.name}}
<span class="arrow" />
</dd>
<div v-if="kind" class="detail" @mouseenter="sover" @mouseleave="sout">
<div v-for="(item,index2) in curdetail.child" :key="index2">
<h4>{{item.title}}</h4>
<span v-for="(child, index3) in item.child" :key="index3">{{child}}</span>
</div>
</div>
</dl>
</div>
CSS代码
.m-menu {
width: 230px;
height: 475px;
box-sizing: border-box;
margin-top: -50px;
margin-left: 20px;
color: #FFF;
position: relative;
background: linear-gradient(-180deg, rgba(2, 181, 157, .85) 2%, rgba(22, 146, 183, .85) 100%);
dt {
height: 50px;
padding-top: 15px;
box-sizing: border-box;
font-size: 16px;
font-weight: 400;
margin-left: 15px;
}
dd {
position: relative;
box-sizing: border-box;
padding: 2px 12px;
height: 26px;
cursor: pointer;
&:hover {
background: rgba(255, 255, 255, .2);
&>i {
opacity: 1;
}
}
}
.nav {
dd>i {
font-family: 'meituan';
font-size: 14px;
font-style: normal;
opacity: 0.3;
margin-right: 11px;
&:before {
width: 14px;
height: 14px;
display: inline-block;
}
}
.food {
&:before {
content: "\e622";
}
}
.takeout {
&:before {
content: "\e630";
}
}
.hotel {
&:before {
content: "\e62a";
}
}
.homestay {
&:before {
content: "\e631";
}
}
.movie {
&:before {
content: "\e62c";
position: relative;
left: -2px;
}
}
.airport {
&:before {
content: "\e632";
}
}
.ktv {
&:before {
content: "\e627";
}
}
.life {
&:before {
content: "\e633";
}
}
.hair {
&:before {
content: "\e626";
transform: scale(0.7);
}
}
.marry {
&:before {
content: "\e629";
}
}
.offspring {
&:before {
content: "\e623";
}
}
.sport {
&:before {
content: "\e62b";
}
}
.furniture {
&:before {
content: "\e625";
}
}
.study {
&:before {
content: "\e624";
}
}
.health {
&:before {
content: "\e628";
}
}
.bar {
&:before {
content: "\e621";
}
}
.arrow {
width: 4px;
height: 4px;
border-bottom: 1px solid #fff;
border-right: 1px solid #fff;
transform: rotate(-45deg);
display: block;
position: absolute;
right: 13px;
top: 0;
bottom: 0;
margin: auto;
}
}
.detail {
padding: 0 30px;
position: absolute;
left: 230px;
bottom: 0;
width: 400px;
height: 416px;
background: #fff;
z-index: 9999;
h4 {
margin-top: 24px;
height: 22px;
line-height: 22px;
padding-bottom: 10px;
border-bottom: 1px solid #e5e5e5;
}
span {
color: #999;
font-size: 12px;
line-height: 15px;
display: inline-block;
margin-right: 16px;
margin-top: 10px;
cursor: pointer;
&:hover {
color: #31BBAC;
}
}
}
}
JavaScript逻辑代码
data() {
return {
kind: '',
menu: [
{
type: 'food',
name: '美食',
child: [
{
title: '美食',
child: ['代金券', '甜点', '小吃', '快餐', '外卖', '油泼辣子面'],
},
],
},
{
type: 'takeout',
name: '外卖',
child: [
{
title: '外卖',
child: [
'肉夹馍',
'火腿',
'火烧',
'尖椒肉丝',
'葱花鸡蛋',
'酱猪蹄',
],
},
],
},
{
type: 'hotel',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'homestay',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'movie',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'airport',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'ktv',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'life',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'hair',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'marry',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'offspring',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'sport',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'furniture',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'study',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'health',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
{
type: 'bar',
name: '酒店',
child: [
{
title: '酒店',
child: [
'4星级酒店',
'5星级酒店',
'3星级酒店',
'2星级酒店',
'2星级酒店',
],
},
],
},
],
}
},
computed: {
curdetail() {
//进行过滤
return this.menu.filter((item) => item.type === this.kind)[0]
},
},
mounted() {},
methods: {
mouseleave() {
//延迟
this._timer = setTimeout(() => {
this.kind = ''
}, 150)
},
enter(e) {
//拿到移动的class
this.kind = e.target.querySelector('i').className
},
sover() {
//清除
clearTimeout(this._timer)
},
sout() {
this.kind = ''
},
},
//熟悉vue项目的都能看懂
谢谢观看,如有不足,敬请指教