效果图
开发环境
vue3
关键逻辑
//导航栏状态选择
const navbarSolid = ref(false);
//初始化导航栏高度
const navbarHeight = ref(0);
/**
* 根据滚动距离改变样式
*/
function checkNavbarOpacity() {
navbarSolid.value = window.pageYOffset > navbarHeight.value / 2;
}
/**
* 绑定window的scroll事件
*/
onMounted(() => {
// 获取导航栏高度
navbarHeight.value = document.querySelector('nav').offsetHeight;
window.addEventListener('scroll', checkNavbarOpacity);
});
/**
* 解绑window的scroll事件
*/
onUnmounted(() => {
window.removeEventListener('scroll', checkNavbarOpacity);
});
实现代码
<template>
<nav :class="{ 'afterNav': navbarSolid, 'beforeNav': !navbarSolid }">
<div class="text">
<span class="nav-logo" @click="router.push('/')">月木天上</span>
<div class="nav-list">
<div class="nav-item" v-for="(nav,index) in navList" :key="index">
<span @click="router.push(nav.path)">{{ nav.name }}</span>
</div>
</div>
</div>
</nav>
</template>
<script setup>
import {onMounted, onUnmounted, reactive, ref} from 'vue';
import {useDataStore} from "@/stores/dataStore"
import {useRouter} from "vue-router";
const router = useRouter()
const dataStore = useDataStore()
//初始化导航列表
const navList = reactive([
{
name: '首页',
path: '/home/index'
},
{
name: '导航',
path: '/home/nav'
},
{
name: '课程',
path: '/course/index'
},
{
name: '博客',
path: '/blog/index'
},
{
name: '商城',
path: '/shop/index'
},
{
name: '联系我们',
path: '/home/contact'
},
])
//导航栏状态选择
const navbarSolid = ref(false);
//初始化导航栏高度
const navbarHeight = ref(0);
/**
* 根据滚动距离改变样式
*/
function checkNavbarOpacity() {
navbarSolid.value = window.pageYOffset > navbarHeight.value / 2;
}
/**
* 绑定window的scroll事件
*/
onMounted(() => {
// 获取导航栏高度
navbarHeight.value = document.querySelector('nav').offsetHeight;
window.addEventListener('scroll', checkNavbarOpacity);
});
/**
* 解绑window的scroll事件
*/
onUnmounted(() => {
window.removeEventListener('scroll', checkNavbarOpacity);
});
</script>
<style scoped lang="scss">
/* 初始样式 */
.beforeNav {
position: fixed;
width: 100%;
transition: background-color 0.3s;
.text {
margin-top: 30px;
.nav-logo {
color: #fff;
float: left;
margin-left: 12%;
font-family: 楷体;
font-weight: bolder;
font-size: 2em;
}
.nav-logo:hover {
cursor: pointer;
}
.nav-list {
display: flex;
margin-left: 49%;
.nav-item {
margin-left: 30px;
font-family: 楷体;
font-size: 1.5em;
color: #a5d2e3;
}
.nav-item:hover {
text-decoration: underline;
cursor: pointer; /*变小手*/
color: #ffffff;
}
}
}
}
/* 下拉后样式 */
.afterNav {
background-color: #ffffff;
z-index: 100;
position: fixed;
width: 100%;
transition: background-color 0.3s;
box-shadow: 0 0 9px 0 rgb(0 0 0 / 10%);
.text {
margin-top: 15px;
margin-bottom: 15px;
.nav-logo {
color: #52d3aa;
float: left;
margin-left: 12%;
font-family: 楷体;
font-weight: bolder;
font-size: 2em;
}
.nav-logo:hover {
cursor: pointer;
}
.nav-list {
display: flex;
margin-left: 50%;
.nav-item {
margin-left: 30px;
font-family: 楷体;
font-size: 1.5em;
color: #7f7f7f;
}
.nav-item:hover {
text-decoration: underline;
cursor: pointer; /*变小手*/
color: #52d3aa;
}
}
}
}
</style>