技术栈:Vue3+Vite+Ts、tailwindcss
<!-- -->
<template>
<div
class="bg-[url('@/assets/images/phone_model.png')] relative overflow-hidden bg-contain bg-no-repeat w-[368px] h-[650px] py-20 px-4">
<div class="absolute z-10 bg-[#f1f1f1] w-[40px] h-[20px] bottom-[70px] duration-500"
:style="{ left, 'border-radius': '0 0 40px 40px' }">
<div ref="ball" class="w-[30px] h-[30px] bg-white rounded-full relative left-[5px] bottom-[15px]"
:class="{ 'animation': animation }"></div>
</div>
<div
class="absolute bg-white bottom-12 left-4 right-4 border-0 border-t-[1px] border-solid flex justify-around border-[#f1f1f1] cursor-pointer">
<div v-for="item in btnGroup" :key="item.id" @click="handleClick(item.id, $event)"
class=" flex-1 text-center pt-5 border-0 border-solid border-r-[1px] last-of-type:border-0 border-[#f1f1f1] duration-500 select-none"
:class="{ 'text-blue-400': active === item.id }">
{{ item.label }}
</div>
</div>
</div>
</template>
<script lang='ts' setup>
const left = ref('42px')
const active = ref(1)
const animation = ref(false)
const ball = ref<HTMLElement | null>()
const btnGroup = [
{ id: 1, label: '首页' },
{ id: 2, label: '动态' },
{ id: 3, label: '购物车' },
{ id: 4, label: '我的' },
]
const handleClick = (id: number, e: any) => {
active.value = id
animation.value = true
setTimeout(() => {
animation.value = false
}, 500);
left.value = `${e.srcElement.offsetLeft + 42}px`
}
</script>
<style scoped lang="scss">
@keyframes leftToRight {
0% {
bottom: 15px;
}
50% {
bottom: 45px;
}
0% {
bottom: 15px;
}
}
.animation {
animation: leftToRight 0.5s;
}
</style>