直接上代码
<template>
<div class="switchTab">
<ul class="container">
<li
class="switchItem"
ref="switchItem"
v-for="(item, index) in FDATA.tabList || tabList"
@click="liHandle(index)"
:key="item.text"
>
<span class="icon">
<i :class="item.icon"></i>
</span>
<span class="text">{{ item.text }}</span>
</li>
<div class="background"></div>
</ul>
</div>
</template>
<!--ts代码-->
<script lang="ts" setup>
import { onMounted, ref } from "vue";
let FDATA = defineProps({
tabList: {
type: Array,
},
num: {
type: Number,
},
color: {
type: String,
default: "#da1e5d",
},
});
const tabList: Array<object> = [
{
icon: "el-icon-s-home",
text: "首页",
},
{
icon: "el-icon-s-grid",
text: "分类",
},
{
icon: "el-icon-share",
text: "分享",
},
{
icon: "el-icon-s-order",
text: "清单",
},
{
icon: "el-icon-user-solid",
text: "我的",
},
];
const switchItem = ref(null);
onMounted(() => {
switchItem.value &&
(switchItem.value[FDATA.num ? FDATA.num - 1 : 0] as any).classList.add(
"active"
);
});
const liHandle = function (i: number): void {
let domList = document.querySelectorAll(".switchItem");
domList.forEach((item, index) => {
if (i === index) {
item.classList.add("active");
} else {
item.classList.remove("active");
}
});
};
</script>
<!--js代码-->
<!--<script setup>
import { onMounted, ref } from "vue"
let FDATA = defineProps({
tabList: {
type: Array
},
num: {
type: Number,
},
})
const tabList = [
{
icon: "el-icon-s-home",
text: "首页",
},
{
icon: "el-icon-s-grid",
text: "分类",
},
{
icon: "el-icon-share",
text: "分享",
},
{
icon: "el-icon-s-order",
text: "清单",
},
{
icon: "el-icon-user-solid",
text: "我的",
},
]
const switchItem = ref(null)
onMounted(() => {
switchItem.value[FDATA.num - 1 || 0].classList.add(
"active"
)
})
const liHandle = function (i) {
let domList = document.querySelectorAll(".switchItem")
domList.forEach((item, index) => {
if (i === index) {
item.classList.add("active")
} else {
item.classList.remove("active")
}
})
};
</script>-->
<style lang="scss" scoped>
* {
caret-color: rgba(0, 0, 0, 0);
}
@keyframes shake {
10% {
transform: rotate(5deg);
}
20% {
transform: rotate(-5deg);
}
30% {
transform: rotate(5deg);
}
40% {
transform: rotate(-5deg);
}
50% {
transform: rotate(5deg);
}
60% {
transform: rotate(-5deg);
}
70% {
transform: rotate(5deg);
}
80% {
transform: rotate(-5deg);
}
90% {
transform: rotate(5deg);
}
100% {
transform: rotate(-5deg);
}
}
.switchTab {
width: 400px;
height: 80px;
position: absolute;
right: 0;
left: 0;
bottom: 100px;
display: flex;
margin: 0 auto;
ul {
width: 100%;
height: 100%;
background-color: #fff;
border-radius: 5px;
display: flex;
align-items: center;
li {
float: left;
width: 80px;
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
.icon {
font-size: 35px;
font-weight: 700;
transform: translateY(10px);
transition: 0.3s;
z-index: 3;
}
.text {
font-size: 15px;
font-weight: 700;
transform: translateY(30px);
transition: 0.3s;
opacity: 0;
}
}
li:hover {
.icon {
transform: rotate(5deg);
animation: shake 0.5s infinite linear;
}
}
li.active:hover {
.icon {
animation: none;
}
}
li.active {
.icon {
font-size: 35px;
font-weight: 700;
transform: translateY(-30px);
}
.text {
font-size: 15px;
font-weight: 700;
transform: translateY(0px);
opacity: 0.8;
}
}
.background {
width: 60px;
height: 60px;
--color: v-bind(FDATA.color);
background-color: var(--color);
position: absolute;
top: -35%;
left: 9px;
border-radius: 50%;
border: 5px solid #333;
box-sizing: border-box;
transition: 0.3s;
}
.background:before {
content: "";
width: 12px;
height: 12px;
position: absolute;
left: -15px;
top: 46%;
border-top-right-radius: 100%;
box-shadow: 2px -2px 0 1px #333;
}
.background:after {
content: "";
width: 12px;
height: 12px;
position: absolute;
right: -15px;
top: 46%;
border-top-left-radius: 100%;
box-shadow: -1px -4px 0 1px #333;
}
}
}
.container li:nth-child(1).active ~ .background {
transform: translateX(80px * 0);
}
.container li:nth-child(2).active ~ .background {
transform: translateX(80px * 1);
}
.container li:nth-child(3).active ~ .background {
transform: translateX(80px * 2);
}
.container li:nth-child(4).active ~ .background {
transform: translateX(80px * 3);
}
.container li:nth-child(5).active ~ .background {
transform: translateX(80px * 4);
}
</style>
在父组件中引入并传参
import switchTab from "@/components/switchTab.vue";
<switchTab :tabList="tabList" :num="3" :color="'#ccc'"></switchTab>