vue3實現(xiàn)tabs導(dǎo)航欄點擊每個導(dǎo)航項有下劃線動畫效果
vue3實現(xiàn)tabs導(dǎo)航欄,點擊每個導(dǎo)航項有下劃線動畫效果
<template>
<div class="navigation">
<div
v-for="(item, index) in items"
:key="index"
class="navigation-item"
:class="{ active: index === activeIndex }"
@click="activeIndex = index"
ref="itemRefs"
>
{{ item }}
</div>
<div
class="navigation-underline"
:class="{ active: activeIndex !== -1 }"
:style="underlineStyle"
ref="underlineRef"
></div>
</div>
</template>
<script setup>
import { ref, watch, onMounted } from "vue";
const activeIndex = ref(0);
const items = ref(["Home", "About", "Services", "Services"]);
const underlineStyle = ref({
transform: "translateX(0)",
});
const itemRefs = ref([]);
const underlineRef = ref(null);
const updateUnderline = () => {
// 獲取標題的寬度,減去下劃線的寬度除以2,可以使下劃線在標題下居中顯示
const item = itemRefs.value[activeIndex.value];
const underline = underlineRef.value;
let newLeft = Number((item.offsetWidth - underline.offsetWidth)) / 2;
if (item && underline) {
const { offsetLeft } = item;
console.log(offsetLeft);
underlineStyle.value = {
transform: `translateX(${offsetLeft + newLeft}px)`,
};
}
};
watch(activeIndex, () => {
updateUnderline();
});
onMounted(() => {
updateUnderline();
});
</script>
<style>
.navigation {
width: 400px;
display: flex;
align-items: center;
justify-content: space-around;
position: relative;
padding: 0 20px;
height: 50px;
font-size: 16px;
font-weight: bold;
}
.navigation-item {
cursor: pointer;
}
.navigation-item.active {
color: #f00;
}
.navigation-underline {
/* 下劃線的寬度 */
width: 50px;
height: 3px;
border-radius: 2px;
position: absolute;
bottom: 0;
left: 0;
background-color: #f00;
transition: all 0.3s ease-in-out;
}
.navigation-underline.active {
transform: translateY(-3px);
}
</style>效果圖:

vue 實現(xiàn)類似于錨點滑動 或者點擊不同的tab時添加下劃線并滑動到對應(yīng)的盒子,手動滑動下劃線也隨位置變動
1、這個方法有個不好的地方就是要自己算每個盒子要滑動的高度,下面是結(jié)構(gòu)
<ul>
<li class="liTem" :class="{ acver: currentTab === 'tab1' }" @click="scrollToTab('tab1')">首頁</li>
<li class="liTem" :class="{ acver: currentTab === 'tab2' }" @click="scrollToTab('tab2')">服務(wù)內(nèi)容</li>
<li class="liTem" :class="{ acver: currentTab === 'tab3' }" @click="scrollToTab('tab3')">業(yè)務(wù)案例</li>
<li class="liTem" :class="{ acver: currentTab === 'tab4' }" @click="scrollToTab('tab4')">關(guān)于我們</li>
<li class="liTem" :class="{ acver: currentTab === 'tab5' }" @click="scrollToTab('tab5')">聯(lián)系方式</li>
</ul>
<div class="section1 " id="section1">Section 1</div>
<div class="section2 " id="section2">Section 2</div>
<div class="section3 " id="section3">Section 3</div>2、簡單寫點css
.tabsul {
position: fixed;
top: 0;
left: 0;
width: 100%;
background-color: #f0f0f0;
display: flex;
justify-content: center;
z-index: 1000;
}
.liTem {
padding: 0 0px 5px 0px;
box-sizing: border-box;
height: 35px;
text-align: center;
font-size: 16px;
font-weight: 500;
margin: 0 20px;
cursor: pointer;
}
.section {
display: flex;
justify-content: center;
font-size: 24px;
color: #fff;
border: 1px solid #ccc;
}
.section1{
height: 430px;
background: #48a994;
}
.section2{
height: 1200px;
background: #49396f;
}
.section3{
height: 600px;
background: #349f64;
}
.section4{
height: 1200px;
background: #9c7d39;
}
.acver {
font-size: 16px;
font-weight: 500;
border-bottom: 3px #ff8000 solid;
}3、在data里聲明這些變量
currentTab: "tab1",
tabScrollPositions: {
// 每個tab對應(yīng)的滾動位置
tab1: 0,
tab2: 670,
tab3: 1700,
// tab4: 4360,
tab4: 3760,
tab5: 5015,
},4、這里寫點擊事件
mounted() {
window.addEventListener("scroll", this.handleScroll);
},
beforeDestroy() {
window.removeEventListener("scroll", this.handleScroll);
},
methods: {
scrollToTab(tab) {
this.currentTab = tab;
const position = this.tabScrollPositions[tab];
window.scrollTo({
top: position,
behavior: "smooth",
});
},
handleScroll() {
const scrollTop =
window.pageYOffset ||
document.documentElement.scrollTop ||
document.body.scrollTop;
for (const tab in this.tabScrollPositions) {
if (
scrollTop >= this.tabScrollPositions[tab] - 50 &&
scrollTop < this.tabScrollPositions[tab] + 50
) {
// 假設(shè)50是閾值
this.currentTab = tab;
break;
}
}
},
}到此這篇關(guān)于vue3實現(xiàn)tabs導(dǎo)航欄點擊每個導(dǎo)航項有下劃線動畫效果的文章就介紹到這了,更多相關(guān)vue3 tabs導(dǎo)航欄內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue源碼解析之Template轉(zhuǎn)化為AST的實現(xiàn)方法
這篇文章主要介紹了Vue源碼解析之Template轉(zhuǎn)化為AST的實現(xiàn)方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
vue-pdf插件實現(xiàn)pdf文檔預(yù)覽方式(自動分頁預(yù)覽)
這篇文章主要介紹了vue-pdf插件實現(xiàn)pdf文檔預(yù)覽方式(自動分頁預(yù)覽),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03
vue中modal傳輸數(shù)據(jù)并刷新部分頁面數(shù)據(jù)方式
這篇文章主要介紹了vue中modal傳輸數(shù)據(jù)并刷新部分頁面數(shù)據(jù)方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-04-04
vue2自定義組件通過rollup配置發(fā)布到npm的詳細步驟
這篇文章主要介紹了vue2自定義組件通過rollup配置發(fā)布到npm,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03
vue element-ui里的table中表頭與表格出現(xiàn)錯位的解決
這篇文章主要介紹了vue element-ui里的table中表頭與表格出現(xiàn)錯位的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08

