先看样例图,一行占满三个元素,默认第一个占总宽的50%,点击谁,被点击的会缓动的放大挤压动画,去占据50%宽度
1、先看html代码
<div class="container" ref="container">
<div class="rectangle" v-for="(item, index) in items" :key="index" :style="{ width: item.width, }" :class="{ clicked: item.clicked }" @click="toggleClick(index)">
<div class="image" :class="{ small: !item.clicked, big: item.clicked }">
<div class="image-font-f" v-if="item.clicked == false">
<div class="textf1" style="color: #000;font-size: 2rem;">{{ item.title }}</div>
<div class="textf2" style="color: #9FB2D2;margin-top: .66rem;letter-spacing: 1.5px;">{{ item.entitle }}</div>
</div>
<div class="image-font-t" v-if="item.clicked == true">
<div class="textt1" style="color: #002864;font-size: 4.5rem;">{{ item.title }}</div>
<div class="textt2" style="color: #A1A9BA;margin: 1.5rem 0;font-size: 1.5vw;letter-spacing: 2px;">{{ item.entitle }}</div>
<div class="textt3" style="color: #002864;white-space: pre-wrap;font-size: 1.5rem;">{{ item.description }}</div>
<div style="color: #7FA6D0;font-weight: 900;margin-top:1.7rem;">━━━</div>
</div>
</div>
</div>
</div>
2、script代码
<script lang="ts">
import { ref, onMounted, nextTick } from "vue";
import { onUnmounted } from "@vue/runtime-core";
export default {
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
setup() {
// 定义矩形元素的初始状态
const items = ref([
{
width: "50%",
marginLeft: "0px",
clicked: true,
title: "XX",
entitle: "xxxx",
description: "xxxxxxxxxxxxxxxx",
},
{
width: "calc(50% / 2 - 5px)",
marginLeft: "5px",
clicked: false,
title: "yy",
entitle: "yyyyy",
description: "yyyyyyyyyyyyyyyy",
},
{
width: "calc(50% / 2 - 5px)",
marginLeft: "5px",
clicked: false,
title: "zz",
entitle: "zzzzzzzz",
description: "zzzzzzzzzzzzzzzz",
},
]);
// 点击矩形元素时切换状态
const toggleClick = (index: number) => {
items.value.forEach((item, i) => {
if (i === index) {
item.clicked = true;
item.width = "50%";
item.marginLeft = "5px";
} else {
item.clicked = false;
item.width = "calc(50% / 2 - 5px)";
item.marginLeft = "5px";
}
});
};
// 在组件挂载时,调整矩形元素的宽度和间距,使其适应容器的宽度
const adjustItems = () => {
const container = document.querySelector(".container");
if (!container) return;
const containerWidth = container.clientWidth;
const itemWidth = containerWidth / 2;
const itemMargin = (containerWidth - itemWidth * 5) / 2;
items.value.forEach(
(item: { width: string; marginLeft: string }, index: number) => {
item.width = index === 0 ? `${itemWidth}px` : `${itemWidth / 2}px`;
item.marginLeft = index === 0 ? "0px" : `${itemMargin}px`;
}
);
};
// 在组件挂载后和窗口大小变化时,调整矩形元素的宽度和间距,使其适应容器的宽度
onMounted(() => {
nextTick(() => {
adjustItems();
});
window.addEventListener("resize", adjustItems);
});
// 在组件卸载时,移除窗口大小变化事件的监听器
onUnmounted(() => {
window.removeEventListener("resize", adjustItems);
});
return { items, toggleClick };
},
};
</script>
3、css代码
<style lang="scss" scoped>
.container {
width: 100%;
display: flex;
justify-content: space-evenly;
height: 35rem;
margin: 0 auto;
}
.rectangle {
position: relative;
height: 100%;
margin-right: 10px;
background-color: #ccc;
display: flex;
justify-content: center;
align-items: center;
transition: width 0.5s ease-in-out;
cursor: pointer;
border-radius: 10px;
// box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.2);
box-shadow: 0px 8px 20px 0px rgba(55, 99, 170, 0.2);
}
.rectangle:first-child {
width: 50%;
}
.rectangle:not(:first-child) {
width: calc(50% / 4 - 5px);
}
.rectangle.clicked {
width: 50%;
margin-left: 5px;
// border-radius: 10px;
}
.image {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: contain;
background-repeat: no-repeat;
.image-font-f {
position: relative;
margin-top: 7rem;
margin-left: 2rem;
font-weight: 600;
}
.image-font-t {
position: relative;
margin-top: 7rem;
margin-left: 2rem;
font-weight: 600;
}
}
.image.small {
background-image: url("../../../public/img/solution/home_one.png");
background-size: 105% 103%;
background-position: -0.38rem -0.33rem;
background-color: #fff;
// border-radius: 10px;
}
.image.big {
background-image: url("../../../public/img/solution/home_one_bg.png");
background-color: #fff;
background-repeat: no-repeat;
background-size: 102% 103%;
background-position: -0.33rem -0.33rem;
// border-radius: 10px;
}
.rectangle:nth-child(2) .image.small {
background-image: url("../../../public/img/solution/home_two.png");
background-size: 105% 103%;
background-position: -0.38rem -0.33rem;
background-color: #fff;
// border-radius: 10px;
}
.rectangle:nth-child(2) .image.big {
background-image: url("../../../public/img/solution/home_two_bg.png");
background-color: #fff;
background-repeat: no-repeat;
background-size: 102% 103%;
background-position: -0.33rem -0.33rem;
// border-radius: 10px;
}
.rectangle:nth-child(3) .image.small {
background-image: url("../../../public/img/solution/home_three.png");
background-size: 105% 103%;
background-position: -0.38rem -0.33rem;
background-color: #fff;
// border-radius: 10px;
}
.rectangle:nth-child(3) .image.big {
background-image: url("../../../public/img/solution/home_three_bg.png");
background-color: #fff;
background-repeat: no-repeat;
background-size: 102% 103%;
background-position: -0.33rem -0.33rem;
// border-radius: 10px;
}
</style>
以上就是实现这个效果的全部代码了,有需要做这个小东西的话,直接施展CV大法即可