鼠标hover时,列表项变宽,否则变窄

54 阅读1分钟

效果

image.png

image.png

<template>
    <div class="settle-flow">
        <div
            v-for="(item, index) in dataList"
            :key="`settle-flow-item-${index}`"
            :class="getListClass(index)"
            @mouseover="handleEvent(index)"
        >
            <div :class="getItemClass(index)">
                内容区域内容区域
            </div>
        </div>
    </div>
</template>
<script lang="ts">
    export default {
        name: 'Test',
    }
</script>
<script setup lang="ts">
    import { ref, watch } from 'vue'
    import _ from 'lodash'

    const props = defineProps({
        sourceData: {
            type: Array,
            default: () => [],
        },
    })

    const dataList = ref([])
    const activeIndex = ref(0) // 当前选中的index

    watch(
        () => props.sourceData,
        newVal => {
            if (newVal?.length > 0) {
                dataList.value = newVal
            }
        },
        {
            immediate: true,
            deep: true,
        }
    )

    // hover
    const handleEvent = index => {
        activeIndex.value = index
    }

    // 获取列表类名
    const getListClass = (index: number) => {
        return [
            'settle-flow__item',
            'settle-flow__item-transition',
            { 'settle-flow__item-widening': activeIndex.value === index }, // 宽样式
            { 'settle-flow__item-narrow': activeIndex.value !== index }, // 窄样式
        ]
    }

    // 获取子项列表
    const getItemClass = (index: number) => {
        return ['settle-flow__item-back', 'settle-flow__item-transition', `settle-flow__item-back${index}`]
    }
</script>

<style lang="scss" scoped>
    @import './index.scss';
</style>

.settle-flow {
    width: 100%;
    display: flex;
    justify-content: center;
    .settle-flow__item {
        height: 360px;
        margin-right: 20px;
        border-radius: 16px;
        background: rgba(255, 255, 255, 0.8);
        &:last-child {
            margin-right: 0px;
        }
        // 用于放背景图
        .settle-flow__item-back {
            width: 100%;
            height: 100%;
            background-repeat: no-repeat;
            background-size: 100% 100%;
        }
    }
    // 窄
    .settle-flow__item-narrow {
        width: 196px; display: none;
        // 可设置某些元素隐藏
        // 01
        .settle-flow__item-back0 {
            background-image: url(窄图);
        }
        // 02
        .settle-flow__item-back1 {
            background-image: url(窄图);
        }
        // 03
        .settle-flow__item-back2 {
            background-image: url(窄图);
        }
    }
    // 变宽
    .settle-flow__item-widening {
        width: 837px;
        // 01
        .settle-flow__item-back0 {
            background-image: url(宽图);
        }
        // 02
        .settle-flow__item-back1 {
            background-image: url(宽图);
        }
        // 03
        .settle-flow__item-back2 {
            background-image: url(宽图);
        }
    }
    .settle-flow__item-transition {
        transition: all 0.3s ease; /* 平滑过渡效果 */
    }
}