思路:先将容器里面的使用flex或者其他布局,一行排列,然后根据数组的下标是否与鼠标放上去获取的Id一致,来控制容器的显示和隐藏。
其他文字的变化就是需要根据具体场景来实现控制是否显示隐藏。
在切换的时候加一些动效。
宽度可以根据获取数据的长度来监听,给每一项设置宽度,鼠标放上去的那一项是固定的宽度
<template>
<div id="app">
<!-- 手风琴效果 -->
<div class="container">
<!-- 根据是否是同一index来判断是显示还是隐藏 -->
<div
:class="['list', { show: active == index }, { hide: active != index }]"
:style="{ background: item.color, width: `${itemWidth}rem` }"
v-for="(item, index) in list"
:key="index"
@mouseover="hoverItem(index)"
>
<!-- 下侧的内容 -->
<div class="doubleLineText">
<div class="title">
{{ item.name }}
</div>
<div class="des">
{{ item.desc }}
</div>
</div>
<!-- 右侧的小标题 -->
<div class="signleLineText">
<div class="title">
{{ item.name }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
list: [
{
id: 0,
name: "测试四",
desc: "防护服豪吉积分你DNF你的减肥0",
color: "blue",
},
{
id: 1,
name: "测试一",
desc: "防护服豪吉积分你DNF你的减肥1",
color: "pink",
},
{
id: 2,
name: "测试二",
desc: "防护服豪吉积分你DNF你的减肥2",
color: "green",
},
{
id: 3,
name: "测试三",
desc: "防护服豪吉积分你DNF你的减肥3",
color: "orange",
},
// {
// id: 4,
// name: "测试三",
// color: "orange",
// },
],
active: 0,
// 每一项的宽度,鼠标放上去选中的宽度在css中固定写死
itemWidth: 0,
timer: null,
};
},
watch: {
// 容器宽度监听
list: {
handler(val) {
if (val.length) {
this.itemWidth = 6 / (val.length - 1);
}
},
immediate: true,
},
},
methods: {
hoverItem(index) {
if (this.timer) {
clearTimeout(this.timer)
this.timer = null
}
this.timer = setTimeout(() => {
this.active = index
}, 200)
},
},
};
</script>
<style>
.container {
margin: 0 auto;
display: flex;
justify-content: center;
align-items: center;
width: 1200px;
height: 540px;
background-color: aqua;
}
.list {
color: #fff;
position: relative;
height: 100%;
overflow: hidden;
transition: all 0.5s ease-in-out;
/* 置灰 */
filter: grayscale(100%);
-webkit-filter: grayscale(100%);
-ms-filter: grayscale(100%);
-moz-filter: grayscale(100%);
-o-filter: grayscale(100%);
cursor: pointer;
}
.signleLineText {
position: absolute;
right: 2px;
bottom: 24px;
}
.signleLineText .title {
width: 30px;
}
.doubleLineText {
margin: 0 auto;
width: 600rpx;
height: 1.32rem;
backdrop-filter: blur(4px);
background: rgba(206, 20, 29, 0.8);
opacity: 0.9037;
padding: 0.24rem;
position: absolute;
left: 0;
bottom: 0;
}
.doubleLineText .title {
font-size: 0.24rem;
color: #ffffff;
line-height: 0.29rem;
font-weight: 550;
}
.doubleLineText .description {
margin-top: 0.09rem;
font-size: 0.16rem;
font-weight: 400;
color: #ffffff;
line-height: 0.19rem;
overflow: hidden;
display: -webkit-box;
/* // 显示2行 */
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
word-break: break-all;
}
.show {
width: 600px !important;
/* 恢复原先设置的样式 */
filter: grayscale(0%);
-webkit-filter: grayscale(0%);
-ms-filter: grayscale(0%);
-moz-filter: grayscale(0%);
-o-filter: grayscale(0%);
}
.show .doubleLineText {
animation: showWord 0.5s ease-in-out forwards;
}
.show .signleLineText {
animation: hideWord 0.5s ease-in-out forwards;
}
.hide .doubleLineText {
animation: hideWord 0.5s ease-in-out forwards;
}
.hide .signleLineText {
animation: showWord 0.5s ease-in-out forwards;
}
/* // 隐藏竖文字 */
@keyframes hideWord {
0% {
opacity: 1;
}
25% {
opacity: 0;
}
100% {
opacity: 0;
}
}
/* // 显示横向文案 */
@keyframes showWord {
0% {
opacity: 0;
}
75% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>