导航组件,点击路由跳转到相应路由,保留当前滚动条的滚动量(滚动条位置)。通过导航宽度计算进行滚动条偏移量移动,无需缓存、存储及路由守卫等。
效果:
navigation.vue(导航组件)
<template>
<div class="nav f18 lh56">
<ul ref="scrollContainer">
<li v-for="(nav,index) in navData" :key="index" @click="goUrl(nav.url)" :class="{active:url==nav.url}">{{nav.name}}</li>
</ul>
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, ref, reactive, computed, onMounted, onActivated, onDeactivated,watch} from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
const { proxy } = getCurrentInstance()
//导航数据
const navData = [
{name:"首页-公告资讯",url:"/index"},
{name:"课程中心",url:"/courseCenter"},
{name:"新销售员培训",url:"/hireTraining"},
{name:"已收藏课程",url:"/collectCourse"},
{name:"大咖来支招",url:"/tycoonCounsel"},
{name:"学习排行榜",url:"/studyRank"},
{name:"培训证书",url:"/TrainingCertificate"},
]
//检测路由变换添加样式
let url = ref()
if(route.path){
url.value = route.path
}else{
url.value = navData[0].url
}
//点击跳转
const goUrl = (event) =>{
proxy.$router.push(event)
}
let scrollContainer = ref(null) //获取导航元素
onMounted(() => {
//获取导航条长度(注:.nav ul设置了overflow-x:auto)并根据路由地址滚动到相应位置
for(let i in navData){
if(route.path == navData[i].url){
scrollContainer.value.scrollLeft = i*(scrollContainer.value.scrollWidth/navData.length)
}
}
})
</script>
<style scoped>
.nav{background:#2573e9;}
.nav ul{display:flex;justify-content:space-between;}
.nav li{flex:1;text-align:center;color:#fff;cursor:pointer;}
.nav li.active,.nav li:hover{background:#0249b8;}
@media screen and (max-width:860px) {
.nav{line-height:3.4rem;font-size:1.4rem;}
.nav ul{width:100%;white-space:nowrap;display:block;overflow-x:auto;}
.nav ul::-webkit-scrollbar{width:0;height:0;}
.nav ul li{display:inline-block;padding:0 1rem;}
}
</style>
引用:
<template>
<div>
<!--其他代码-->
<navigation></navigation>
<!--其他代码-->
</div>
</template>
<script setup>
import { defineComponent, getCurrentInstance, ref, reactive, computed, onMounted, onActivated, onDeactivated} from 'vue';
//引用导航组件navigation.vue
import navigation from '@/components/navigation.vue'
//其他代码
</script>
<style scoped>
</style>