vue3+typeScript 手风琴(每周一个小组件)

每周一个小组件

前言

实现功能:带切换动画效果的手风琴
每周分享一个vue3+typeScript的小组件,我只想分享下自己的实现思路,楼主是个菜鸡前端,记录下实现过程,说不定对你有帮助。

效果展示

预览地址
github地址

moyf9-azzef.gif

开发过程

思路:点击手风琴标题传入它的索引,定义一个参数来接收点击的索引,这个参数等于索引就显示手风琴内容。自定义内容可以根据索引来动态显示。

html部分

<div class="accordion">
    <div v-for="(vo,inx) in items" :key="inx">
        <!-- 手风琴标题 -->
        <div class="item" @click="changeItem(vo,inx)">
            {{vo.title}}
        </div>
        <!-- 手风琴内容 -->
        <div class="content" v-show="active==inx&&vo.show">
            {{vo.content}}
            <!-- 可以自定义内容结构 -->
            <div v-if="inx===0">
                我是自定义内容1
            </div>
            <div v-if="inx===1">
                我是自定义内容2
            </div>
            <div v-if="inx===2">
                我是自定义内容3
            </div>
        </div>
    </div>
</div>

ts部分

<script lang="ts">
import {
    defineComponent,
    reactive,
    toRefs
} from 'vue'
export default defineComponent({
    setup() {
        //定义接口类型
        interface ItemObj {
            title: string;
            content: string;
            show: boolean;
        }
        const data = reactive({
            items: [{
                    title: "JavaScript",
                    content: "这是内容1",
                    show: true
                },
                {
                    title: "Java",
                    content: "这是内容2",
                    show: true
                },
                {
                    title: "C++",
                    content: "这是内容3",
                    show: true
                }
            ],
            active: 0,
            changeItem: (vo: ItemObj, inx: number) => {
                //如果重复点击一个栏目item 可以关闭和打开当前栏目手风琴内容
                if (inx === data.active) {
                    vo.show = !vo.show
                } else {
                    vo.show = true
                }
                data.active = inx
            }
        })
        return {
            ...toRefs(data)
        }
    }
})
</script>

css部分

.accordion {
    width: 800px;
    padding: 50px 20px;
    background: #ecf0f3;
    height: 600px;
    .item {
        text-align: center;
        line-height: 80px;
        margin: 0 auto;
        width: 600px;
        height: 80px;
        border-radius: 12px;
        box-shadow: inset 12px 12px 20px #d1d9e6, inset -12px -12px 20px #fff;
        cursor: pointer;
        margin-bottom: 5px;
    }

    @keyframes fadeIn {
        from {
            opacity: 0;
        }

        to {
            opacity: 1;
        }
    }
    .content {
        opacity: 0;
        min-height: 80px;
        width: 600px;
        margin: 0 auto;
        animation-name: fadeIn;
        animation-duration: 1s;
        animation-fill-mode: both;
    }
}

vue3持续更新中...

本文章由javascript技术分享原创和收集

发表评论 (审核通过后显示评论):