创建顶部导航

导航组件,在layout文件夹下面新建

ResponsiveNavbar.vue

<template><nav class="navbar" :class="{ 'navbar--mobile': isMobile }"><div class="navbar-container"><!-- Logo --><div class="navbar-logo"><router-link to="/" class="logo-link"><span class="logo-text">YourLogo</span></router-link></div><!-- 桌面端导航菜单 --><div v-if="!isMobile" class="navbar-menu"><ul class="menu-list"><li v-for="(item, index) in menuItems" :key="index" class="menu-item"@click="activeMenu(index)"><router-link :to="item.path" class="menu-link":class="{ 'menu-link--active': activeItem === index || item.active }">{{ item.name }}</router-link></li></ul></div><!-- 移动端汉堡菜单按钮 --><div v-else class="navbar-hamburger" @click="toggleMobileMenu"><span class="hamburger-line"></span><span class="hamburger-line"></span><span class="hamburger-line"></span></div></div><!-- 移动端下拉菜单 --><div v-if="isMobile && showMobileMenu" class="navbar-mobile-menu"><ul class="mobile-menu-list"><li v-for="(item, index) in menuItems" :key="index" class="mobile-menu-item"@click="closeMobileMenu"><router-link :to="item.path" class="mobile-menu-link">{{ item.name }}</router-link></li></ul></div></nav>
</template><script setup>
import { ref, onMounted, onUnmounted } from 'vue';
//从路由配置里面获取路由
import {routes} from '@/router';//根据layout过滤,得到需要展示的导航
const menuItems = [];
routes.filter(d=>{if(d.layout){let menu = {name: d.layout.name,path: d.path,active: false}if(window.location.pathname == d.path){menu.active = true}menuItems.push(menu)}
})// 响应式状态
const isMobile = ref(false);
const showMobileMenu = ref(false);
const activeItem = ref(null);const activeMenu = (index) => {activeItem.value = indexmenuItems.filter(d => {d.active = false})
}// 检测屏幕宽度变化
const checkScreenSize = () => {isMobile.value = window.innerWidth < 768;if (!isMobile.value) {showMobileMenu.value = false; // 如果从移动端切换到PC端,关闭移动菜单}
};// 切换移动端菜单显示状态
const toggleMobileMenu = () => {showMobileMenu.value = !showMobileMenu.value;
};// 关闭移动端菜单
const closeMobileMenu = () => {showMobileMenu.value = false;
};// 生命周期钩子
onMounted(() => {checkScreenSize();window.addEventListener('resize', checkScreenSize);
});onUnmounted(() => {window.removeEventListener('resize', checkScreenSize);
});
</script><style scoped>
/* 基础样式 */
.navbar {background-color: #ffffff;box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);position: fixed;top: 0;left: 0;width: 100%;z-index: 1000;transition: all 0.3s ease;
}.navbar-container {display: flex;justify-content: space-between;align-items: center;padding: 0 2rem;height: 70px;max-width: 1200px;margin: 0 auto;
}.logo-link {text-decoration: none;color: #333;font-weight: bold;font-size: 1.5rem;
}.logo-text {color: #4a6cf7;
}/* 桌面端菜单样式 */
.menu-list {display: flex;list-style: none;margin: 0;padding: 0;
}.menu-item {margin: 0 1rem;position: relative;
}.menu-link {color: #333;text-decoration: none;font-weight: 500;padding: 0.5rem 0;transition: all 0.3s ease;position: relative;
}.menu-link:hover {color: #4a6cf7;
}/* 桌面端悬停效果 */
.menu-link::after {content: '';position: absolute;bottom: 0;left: 0;width: 0;height: 2px;background-color: #4a6cf7;transition: width 0.3s ease;
}.menu-link:hover::after {width: 100%;
}.menu-link--active {color: #4a6cf7;
}.menu-link--active::after {width: 100%;
}/* 移动端汉堡菜单 */
.navbar-hamburger {display: flex;flex-direction: column;justify-content: space-between;width: 30px;height: 20px;cursor: pointer;
}.hamburger-line {width: 100%;height: 2px;background-color: #333;transition: all 0.3s ease;
}/* 移动端菜单 */
.navbar-mobile-menu {position: absolute;top: 67px;left: 0;width: 100%;background-color: #ffffff;box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1);z-index: 999;
}.mobile-menu-list {list-style: none;padding: 0;margin: 0;
}.mobile-menu-item {border-bottom: 1px solid #f0f0f0;
}.mobile-menu-link {display: block;padding: 1rem 2rem;color: #333;text-decoration: none;transition: background-color 0.3s ease;
}.mobile-menu-link:hover {background-color: #f5f5f5;
}/* 响应式调整 */
@media (max-width: 768px) {.navbar-container {padding: 0 1rem;}.logo-text {font-size: 1.2rem;}
}/* 移动端导航栏样式 */
.navbar--mobile {height: auto;padding: 0;
}.navbar--mobile .navbar-container {height: auto;padding: 1rem;
}.navbar--mobile .menu-list {flex-direction: column;
}
</style>

修改App.vue

<template><ResponsiveNavbar /><main><!-- 你的页面内容 --><router-view /></main>
</template><script lang="ts">
import { defineComponent } from "vue";
import ResponsiveNavbar from '@/layout/ResponsiveNavbar.vue';
export default defineComponent({name: "app",components: {ResponsiveNavbar}
});
</script>

在router/index.ts添加路由


export const routes = [{path: '/',name: 'Home',component:  () => import('@/views/home/HomeView.vue'),layout: {name: "首页"}},{path: '/blog',name: 'Blog',component: () => import('@/views/blog/blog.vue'),meta: { requiresAuth: false },layout: {name: "文章"}},{path: '/friend',name: 'Friend',component:  () => import('@/views/friend/friend.vue'),layout: {name: "友链"}},{path: '/about',name: 'About',component: () => import('@/views/about/about.vue'),meta: { requiresAuth: false },layout: {name: "关于"}},{path: '/message',name: 'Message',component: () => import('@/views/message/message.vue'),meta: { requiresAuth: false },layout: {name: "留言板"}}
}]

 layout为导航选项,如果该路由是导航,那必须要写,否则就不用写

效果图

 以上仅为展示效果,具体细节还需自己更改

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/88378.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/88378.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI对话导出工具 (AI Chat Exporter)——支持 ChatGPT, Grok 和 Gemini 平台

&#x1f680; AI对话导出工具 (AI Chat Exporter) 轻松将AI对话导出为标准Markdown格式 支持 ChatGPT, Grok 和 Gemini 平台 相关代码已开源至 Github 欢迎Star ✨ 功能特点 &#x1f504; 多平台支持&#xff1a;同时支持 ChatGPT, Grok 和 Gemini 三大AI平台&#x1f4dd;…

【MATLAB代码】基于MVC的EKF和经典EKF对三维非线性状态的滤波,提供滤波值对比、误差对比,应对跳变的观测噪声进行优化

本文所述的代码实现了改进的扩展卡尔曼滤波算法&#xff08;MVC-EKF&#xff09;&#xff0c;针对三维运动估计场景&#xff0c;与经典EKF算法进行性能对比。代码通过引入Versoria函数优化协方差更新过程&#xff0c;显著提升了在测量异常值干扰下的状态估计鲁棒性。 文章目录 …

【Linux】Linux系统的基础操作

目录 常用命令速递 系统目录结构及路径 Linux 常用命令 做两个小项目 据此操作 用户配额 前言 当下&#xff0c;Linux 系统作为开源操作系统&#xff0c;意义和作用重大。技术上&#xff0c;其开源特性极大推动软件开发进步&#xff0c;全球开发者可共同完善&#xff0c…

使用 C++/OpenCV 构建中文 OCR 系统:实现账单、发票及 PDF 读取

使用 C/OpenCV 构建中文 OCR 系统&#xff1a;实现账单、发票及 PDF 读取 在当今数字化浪潮中&#xff0c;自动从文档中提取信息至关重要&#xff0c;尤其是在处理大量账单、发票和 PDF 文件时。光学字符识别&#xff08;OCR&#xff09;技术是实现这一目标的核心。本文将详细…

windows配置Jenkins自动化定时任务+测试报告发送

一、Jenkins的安装步骤 JDK安装 没有JDK的先安装JDKhttps://adoptium.net/zh-CN/temurin/releases/?osany&archany&version21 下载Jenkins 由于JDK 1.8仅适配Jenkins 2.357之前的版本&#xff08;如2.346.1及以下&#xff09;&#xff0c;需从旧版本渠道下载&#xf…

预训练语言模型基础知识概述

文章目录 预处理语言模型的发展预训练语言模型统计语言模型神经网络语言模型 词向量onehot编码词嵌入word embedding Word2Vec模型RNN和LSTMRNNLSTM ELMo模型预训练下游任务 Attention自注意力Masked Self AttentionMulti-head Self Attention 位置编码Transformer概念GPT概念B…

浏览器工作原理24 [#]分层和合成机制:为什么css动画比JavaScript高效

引用 《浏览器工作原理与实践》 本文主要讲解渲染引擎的分层和合成机制&#xff0c;因为分层和合成机制代表了浏览器最为先进的合成技术&#xff0c;Chrome 团队为了做到这一点&#xff0c;做了大量的优化工作。了解其工作原理&#xff0c;有助于拓宽你的视野&#xff0c;而且也…

【数字后端】-什么是RC corner? 每种Corner下有什么区别?

芯片的寄生参数可以在多个corner下提取&#xff0c;他们对应了不同情况的net delay Typical&#xff1a;R和C都是标准值Cmax(Cworst)&#xff1a;C最大的互连角&#xff0c;R小于TypicalCmin(Cbest)&#xff1a;C最小&#xff0c;R大于TypicalRCmax(RCworst)&#xff1a;互连线…

HarmonyOS开发基础 --鸿蒙仓颉语言基础语法入门

仓颉编程语言是华为自主研发的一种面向全场景应用开发的现代编程语言&#xff0c;具有高效编程、安全可靠、轻松并发和卓越性能等特点。本节将简单介绍仓颉语言的部分语法和使用&#xff0c;帮助开发者快速上手。 1.3.1&#xff1a;数据类型 整数 仓颉把整数分为有符号和无符…

Excel文件比较器v1.3,html和js写的

Excel文件比较器v1.3 版本说明&#xff1a;v1.3 1添加支持文件格式&#xff1a;CSV。 2&#xff0c;添加60条历史记录保存功能 - 用于保存比对结果。历史记录保存在浏览器的localStorage中&#xff0c;这是一个浏览器提供的本地存储机制&#xff0c;数据会一直保留直到用户…

Kimi“新PPT助手” ,Kimi全新自研的免费AI生成PPT助手

大家好&#xff0c;这里是K姐。 一个帮你用AI轻松生成精美PPT的女子。 前段时间给大家分享了一期用智能体做PPT的对比测评&#xff0c;很多友友都表示&#xff1a;那 Kimi 呢&#xff1f; 今天偶然发现 Kimi 新增了一个叫“新PPT助手”的功能&#xff0c;立马上手体验了一下…

MySQL DATETIME类型存储空间详解:从8字节到5字节的演变

在MySQL数据库设计中&#xff0c;DATETIME类型用于存储日期和时间信息&#xff0c;但其存储空间大小并非固定不变&#xff0c;而是随MySQL版本迭代和精度定义动态变化。本文将详细说明其存储规则&#xff0c;并提供清晰的对比表格。 一、核心结论 MySQL 5.6.4 是分水岭&#…

Gartner发布中国企业应用生成式AI指南:避免12 个 GenAI 陷阱

GenAI 技术&#xff08;例如 AI 代理和 DeepSeek&#xff09;的快速迭代导致企业抱有不切实际的期望。本研究借鉴了我们与中国 AI 领导者就常见的 GenAI 陷阱进行的讨论&#xff0c;并提供了最终有助于成功采用的建议。 主要发现 接受调查的首席信息官表示&#xff0c;生成式人…

Vue3中ref和reactive的区别与使用场景详解

在 Vue 3 中&#xff0c;响应式系统进行了全新设计&#xff0c;ref 和 reactive 是其中的核心概念。 ### 一、ref 的使用 ref 适用于基本数据类型&#xff0c;也可以用于对象&#xff0c;但返回的是一个带 .value 的包装对象。 js import { ref } from vue const count ref(…

React性能优化:父组件如何导致子组件重新渲染及避免策略

目录 React性能优化&#xff1a;父组件如何导致子组件重新渲染及避免策略什么是重新渲染&#xff1f;父组件如何"无辜"地让子组件重新渲染&#xff1f;示例 1: 基础父组件状态变更示例 2: 传递未变化的原始类型Prop示例 3: 传递引用类型Prop&#xff08;对象&#xf…

图的拓扑排序管理 Go 服务启动时的组件初始化顺序

在构建复杂的 Go 应用程序时&#xff0c;服务的启动过程往往涉及多个组件的初始化&#xff0c;例如日志、配置、数据库连接、缓存、服务管理器、适配器等等。这些组件之间通常存在着复杂的依赖关系&#xff1a;日志可能需要配置信息&#xff0c;数据库连接可能依赖日志和追踪&a…

【物理重建】SPLART:基于3D高斯泼溅的铰链估计与部件级重建

标题&#xff1a;《SPLART: Articulation Estimation and Part-Level Reconstruction with 3D Gaussian Splatting》 项目&#xff1a;https://github.com/ripl/splart 文章目录 摘要一、引言二、相关工作2.1 数据驱动的铰链学习2.2 物体重建的表征方法2.3 铰链物体重建 三、方…

vscode中vue自定义组件的标签失去特殊颜色高亮

遇到的问题 最近接触了一个历史遗留项目时&#xff0c;我遭遇了堪称"史诗级屎山"的代码结构——各种命名混乱的自定义组件和原生HTML标签混杂在一起&#xff0c;视觉上完全无法区分。这让我突然想起&#xff0c;之前在使用vue或者其他框架开发的时候&#xff0c;只要…

【Dify精讲】第19章:开源贡献指南

今天&#xff0c;让我们深入 Dify 的开源贡献体系&#xff0c;看看这个项目是如何在短短时间内聚集起一个活跃的开发者社区的。作为想要参与 Dify 开发的你&#xff0c;这一章将是你的实战指南。 一、代码贡献流程&#xff1a;从想法到合并的完整路径 1.1 贡献前的准备工作 …

Web攻防-CSRF跨站请求伪造Referer同源Token校验复用删除置空联动上传或XSS

知识点&#xff1a; 1、Web攻防-CSRF-原理&检测&利用&防御 2、Web攻防-CSRF-防御-Referer策略隐患 3、Web攻防-CSRF-防御-Token校验策略隐患 一、演示案例-WEB攻防-CSRF利用-原理&构造 CSRF 测试功能点 删除帐户 更改电子邮件 如果不需要旧密码&#xff0c;请…