页面顶部导航栏(Navbar)的功能(Navbar/index.vue)
这段代码是一个 Vue.js 组件,实现了页面顶部导航栏(Navbar)的功能。我将分块分析它的各个部分:
模板 (Template):
<!-- spid-admin/src/layout/components/Navbar/index.vue -->
<template><div class="navbar"><hamburgerid="hamburger-container":is-active="sidebar.opened"class="hamburger-container"@toggleClick="toggleSideBar"/><breadcrumbid="breadcrumb-container"class="breadcrumb-container"/><!-- <lang-select /> --><div class="right-menu"><template v-if="device!=='mobile'"><div style="position: relative; display: inline-block; padding: 0 8px; height: 100%; color: #5a5e66; vertical-align: text-bottom; cursor: pointer;" @click="handleToNotice"><el-image :src="noticePic" style="width: 35px; height: 35px; position: relative; top: 7px;" /></div><div v-if="isVip" style="position: relative; display: inline-block; padding: 0 4px; height: 100%; color: #5a5e66; vertical-align: text-bottom; cursor: pointer;" @click="handleToMission"><el-image :src="systemTaskPic" style="width: 35px; height: 35px; position: relative; top: 7px;" /></div><!-- <header-search class="right-menu-item" /> --><!-- <error-log class="errLog-container right-menu-item hover-effect" /> --><screenfull class="right-menu-item hover-effect" /><!-- <el-tooltip:content="$t('navbar.size')"effect="dark"placement="bottom"><size-select class="right-menu-item hover-effect" /></el-tooltip> --><!-- <lang-select class="right-menu-item hover-effect" /> --><span class="username">{{ username }}</span></template><el-dropdownclass="avatar-container right-menu-item hover-effect"trigger="click"><div class="avatar-wrapper"><imgv-if="avatar":src="oss + avatar"class="user-avatar"><imgv-else:src="require('@/assets/images/logo.jpg')"class="user-avatar"><i class="el-icon-caret-bottom" /></div><el-dropdown-menu slot="dropdown"><router-link to="/"><el-dropdown-item>{{ $t('navbar.dashboard') }}</el-dropdown-item></router-link><router-link to="/setting/profile/"><el-dropdown-item>{{ $t('navbar.profile') }}</el-dropdown-item></router-link><router-link to="/subscribe/list/"><el-dropdown-item>订阅续期</el-dropdown-item></router-link><router-link to="/account/child/"><el-dropdown-item>账号分身</el-dropdown-item></router-link><el-dropdown-itemdivided@click.native="logout"><span style="display:block;">{{ $t('navbar.logOut') }}</span></el-dropdown-item></el-dropdown-menu></el-dropdown></div></div>
</template>
navbar: 导航栏的容器。hamburger: 汉堡按钮,用于切换侧边栏的显示和隐藏,@toggleClick="toggleSideBar"点击事件触发toggleSideBar方法。breadcrumb: 面包屑导航。right-menu: 右侧菜单区域。v-if="device!=='mobile'": 判断当前设备是否为移动设备,如果是,则不显示下列内容。- 通知图标: 使用
el-image显示通知图标,@click="handleToNotice"点击事件触发handleToNotice方法,跳转到通知列表。
- 通知图标: 使用
- 任务图标: 使用
el-image显示任务图标,v-if="isVip"判断用户是否是vip,如果是vip则显示任务图标。@click="handleToMission"点击事件触发handleToMission方法,跳转到任务列表。
*screenfull: 全屏切换按钮。
*username: 显示用户名。 el-dropdown: 下拉菜单,用于显示用户头像和一些操作选项。avatar-wrapper: 头像容器。v-if="avatar": 判断用户是否有头像, 如果有头像,则拼接oss和avatar作为头像的url, 否则使用默认的logo作为头像el-dropdown-menu: 下拉菜单项。router-link: 使用router-link组件创建路由链接。el-dropdown-item: 下拉菜单项。@click.native="logout": 点击退出登录按钮,触发logout方法。
脚本 (Script):
<script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import { AppModule } from '@/store/modules/app'
import { UserModule } from '@/store/modules/user'
import Breadcrumb from '@/components/Breadcrumb/index.vue'
import ErrorLog from '@/components/ErrorLog/index.vue'
import Hamburger from '@/components/Hamburger/index.vue'
import HeaderSearch from '@/components/HeaderSearch/index.vue'
import LangSelect from '@/components/LangSelect/index.vue'
import Screenfull from '@/components/Screenfull/index.vue'
import SizeSelect from '@/components/SizeSelect/index.vue'@Component({name: 'Navbar',components: {Breadcrumb,ErrorLog,Hamburger,HeaderSearch,LangSelect,Screenfull,SizeSelect}
})
export default class extends Vue {get sidebar() {return AppModule.sidebar}get device() {return AppModule.device.toString()}get avatar() {return UserModule.avatar}get username() {return UserModule.username}get oss() {return AppModule.oss}get noticeNum() {// console.log('改变触发')// console.log(AppModule.notices)return AppModule.notices}@Watch('noticeNum')watchV(v: any) {this.setData()}public role = UserModule.roles[0]public isVip: boolean = JSON.parse(UserModule.token).vippublic noticePic = require(`@/assets/images/notice-0.png`)public systemTaskPic = require(`@/assets/images/system-task.png`)private toggleSideBar() {AppModule.ToggleSideBar(false)}private async logout() {await UserModule.LogOut()this.$router.push(`/login?redirect=${this.$route.fullPath}`)}private handleToNotice() {this.$router.push(`/notice/list`)}private handleToMission() {if (this.role === 'ROLE_SUPER') {this.$router.push(`/mission/super-list`)} else {this.$router.push(`/mission/company-list`)}}private async setData() {const num = parseInt(this.noticeNum)this.noticePic = require(`@/assets/images/notice-${!num ? '0' : num > 9 ? 'n' : num}.png`)}created() {this.setData()}
}
</script>
- 引入依赖: 引入
vue-property-decorator,AppModule,UserModule, 以及各种组件。 - 组件定义: 使用
@Component装饰器定义组件,名称为Navbar。 - 计算属性:
sidebar: 获取AppModule中的侧边栏状态。device: 获取AppModule中的设备类型。avatar: 获取UserModule中的用户头像。username: 获取UserModule中的用户名。oss: 获取AppModule中的 OSS 地址前缀。noticeNum: 获取AppModule中的通知数量。
@Watch('noticeNum'): 监听noticeNum的变化,如果发生变化,则调用setData方法。- 数据属性:
role: 获取UserModule中的用户角色。isVip: 获取UserModule中的用户是否是 VIP。noticePic: 通知图标的路径。systemTaskPic: 任务图标的路径。
- 方法:
toggleSideBar(): 调用AppModule.ToggleSideBar()方法切换侧边栏的显示和隐藏。logout(): 调用UserModule.LogOut()方法退出登录,并跳转到登录页。handleToNotice(): 跳转到通知列表页。handleToMission(): 根据用户角色跳转到对应的任务列表页。setData(): 根据通知数量设置noticePic的路径。
- 生命周期钩子:
created(): 调用setData()方法,初始化通知图标。
样式 (Style):
<style lang="scss" scoped>
.navbar {// ... 导航栏样式
}
</style>
navbar: 导航栏容器的样式,设置高度、背景颜色、阴影等。hamburger-container: 汉堡按钮容器的样式,设置高度、浮动、内边距、光标等。breadcrumb-container: 面包屑导航容器的样式,设置浮动。errLog-container: 错误日志容器的样式,设置display: inline-block和vertical-align: top。right-menu: 右侧菜单容器的样式,设置浮动、高度、行高。right-menu-item: 右侧菜单项的样式,设置display: inline-block、内边距、高度、字体大小、颜色等。hover-effect: 鼠标悬停效果,设置光标和过渡效果。avatar-container: 头像容器的样式,设置外边距。avatar-wrapper: 头像包装器的样式,设置外边距和相对定位。user-avatar: 用户头像的样式,设置光标、宽度、高度、圆角。el-icon-caret-bottom: 下拉图标的样式,设置光标、绝对定位、字体大小。username: 用户名的样式,设置display: inline-block、vertical-align: text-bottom、内边距、颜色、字体大小和鼠标悬停效果。
总结:
这段代码实现了一个功能完备的页面顶部导航栏,包括:
- 汉堡按钮
- 面包屑导航
- 通知图标
- 系统任务图标 (VIP用户专属)
- 全屏切换按钮
- 用户名显示
- 用户头像下拉菜单(包含常用操作和退出登录)
代码结构清晰,使用了 Vuex 管理状态,并使用了 vue-property-decorator 简化组件编写。
可以改进的地方:
- 组件拆分: 可以将右侧菜单区域拆分成更小的组件,例如将通知图标、任务图标、用户名和头像下拉菜单拆分成独立的组件,提高代码的可复用性和可维护性。
- 国际化: 可以将硬编码的中文文本替换成国际化资源,例如“订阅续期”、“账号分身”等。
- 错误处理: 可以添加更详细的错误处理,例如在
logout方法中捕获错误并提示用户。 - 代码注释: 可以添加更详细的代码注释,方便其他开发人员理解代码的逻辑。
<!-- spid-admin/src/layout/components/Navbar/index.vue -->
<template><div class="navbar"><hamburgerid="hamburger-container":is-active="sidebar.opened"class="hamburger-container"@toggleClick="toggleSideBar"/><breadcrumbid="breadcrumb-container"class="breadcrumb-container"/><!-- <lang-select /> --><div class="right-menu"><template v-if="device!=='mobile'"><div style="position: relative; display: inline-block; padding: 0 8px; height: 100%; color: #5a5e66; vertical-align: text-bottom; cursor: pointer;" @click="handleToNotice"><el-image :src="noticePic" style="width: 35px; height: 35px; position: relative; top: 7px;" /></div><div v-if="isVip" style="position: relative; display: inline-block; padding: 0 4px; height: 100%; color: #5a5e66; vertical-align: text-bottom; cursor: pointer;" @click="handleToMission"><el-image :src="systemTaskPic" style="width: 35px; height: 35px; position: relative; top: 7px;" /></div><!-- <header-search class="right-menu-item" /> --><!-- <error-log class="errLog-container right-menu-item hover-effect" /> --><screenfull class="right-menu-item hover-effect" /><!-- <el-tooltip:content="$t('navbar.size')"effect="dark"placement="bottom"><size-select class="right-menu-item hover-effect" /></el-tooltip> --><!-- <lang-select class="right-menu-item hover-effect" /> --><span class="username">{{ username }}</span></template><el-dropdownclass="avatar-container right-menu-item hover-effect"trigger="click"><div class="avatar-wrapper"><imgv-if="avatar":src="oss + avatar"class="user-avatar"><imgv-else:src="require('@/assets/images/logo.jpg')"class="user-avatar"><i class="el-icon-caret-bottom" /></div><el-dropdown-menu slot="dropdown"><router-link to="/"><el-dropdown-item>{{ $t('navbar.dashboard') }}</el-dropdown-item></router-link><router-link to="/setting/profile/"><el-dropdown-item>{{ $t('navbar.profile') }}</el-dropdown-item></router-link><router-link to="/subscribe/list/"><el-dropdown-item>订阅续期</el-dropdown-item></router-link><router-link to="/account/child/"><el-dropdown-item>账号分身</el-dropdown-item></router-link><el-dropdown-itemdivided@click.native="logout"><span style="display:block;">{{ $t('navbar.logOut') }}</span></el-dropdown-item></el-dropdown-menu></el-dropdown></div></div>
</template><script lang="ts">
import { Component, Vue, Watch } from 'vue-property-decorator'
import { AppModule } from '@/store/modules/app'
import { UserModule } from '@/store/modules/user'
import Breadcrumb from '@/components/Breadcrumb/index.vue'
import ErrorLog from '@/components/ErrorLog/index.vue'
import Hamburger from '@/components/Hamburger/index.vue'
import HeaderSearch from '@/components/HeaderSearch/index.vue'
import LangSelect from '@/components/LangSelect/index.vue'
import Screenfull from '@/components/Screenfull/index.vue'
import SizeSelect from '@/components/SizeSelect/index.vue'@Component({name: 'Navbar',components: {Breadcrumb,ErrorLog,Hamburger,HeaderSearch,LangSelect,Screenfull,SizeSelect}
})
export default class extends Vue {get sidebar() {return AppModule.sidebar}get device() {return AppModule.device.toString()}get avatar() {return UserModule.avatar}get username() {return UserModule.username}get oss() {return AppModule.oss}get noticeNum() {// console.log('改变触发')// console.log(AppModule.notices)return AppModule.notices}@Watch('noticeNum')watchV(v: any) {this.setData()}public role = UserModule.roles[0]public isVip: boolean = JSON.parse(UserModule.token).vippublic noticePic = require(`@/assets/images/notice-0.png`)public systemTaskPic = require(`@/assets/images/system-task.png`)private toggleSideBar() {AppModule.ToggleSideBar(false)}private async logout() {await UserModule.LogOut()this.$router.push(`/login?redirect=${this.$route.fullPath}`)}private handleToNotice() {this.$router.push(`/notice/list`)}private handleToMission() {if (this.role === 'ROLE_SUPER') {this.$router.push(`/mission/super-list`)} else {this.$router.push(`/mission/company-list`)}}private async setData() {const num = parseInt(this.noticeNum)this.noticePic = require(`@/assets/images/notice-${!num ? '0' : num > 9 ? 'n' : num}.png`)}created() {this.setData()}
}
</script><style lang="scss" scoped>
.navbar {height: 50px;overflow: hidden;position: relative;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);.hamburger-container {line-height: 46px;height: 100%;float: left;padding: 0 15px;cursor: pointer;transition: background .3s;-webkit-tap-highlight-color:transparent;&:hover {background: rgba(0, 0, 0, .025)}}.breadcrumb-container {float: left;}.errLog-container {display: inline-block;vertical-align: top;}.right-menu {float: right;height: 100%;line-height: 50px;&:focus {outline: none;}.right-menu-item {display: inline-block;padding: 0 8px;height: 100%;font-size: 22px;color: #5a5e66;vertical-align: text-bottom;&.hover-effect {cursor: pointer;transition: background .3s;&:hover {background: rgba(0, 0, 0, .025)}}}.avatar-container {margin-right: 30px;.avatar-wrapper {margin-top: 5px;position: relative;.user-avatar {cursor: pointer;width: 40px;height: 40px;border-radius: 10px;}.el-icon-caret-bottom {cursor: pointer;position: absolute;right: -20px;top: 25px;font-size: 12px;}}}}.username {display: inline-block;vertical-align: text-bottom;padding: 0 8px;color: #1890ff;font-size: 12px;&:hover {color: #46a6ff;}}
}
</style>

相关文章:
页面顶部导航栏(Navbar)的功能(Navbar/index.vue)
这段代码是一个 Vue.js 组件,实现了页面顶部导航栏(Navbar)的功能。我将分块分析它的各个部分: 模板 (Template): <!-- spid-admin/src/layout/components/Navbar/index.vue --> <template><div class"navb…...
thinnkphp5.1和 thinkphp6以及nginx,apache 解决跨域问题
ThinkPHP 5.1 使用中间件设置响应头 ThinkPHP 5.1 及以上版本支持中间件,可以通过中间件统一设置跨域响应头。 步骤: 创建一个中间件文件,例如 CorsMiddleware.php: namespace app\middleware;class CorsMiddleware {public fu…...
vue2新增删除
(只是页面实现,不涉及数据库) list组件: <button click"onAdd">新增</button><el-table:header-cell-style"{ textAlign: center }" :cell-style"{ textAlign: center }":data&quo…...
测试ip端口-telnet开启与使用
前言 开发过程中我们总会要去测试ip通不通,或者ip下某个端口是否可以联通,为此我们可以使用telnet 命令来实现。 一、telnet 开启 可能有些人使用telnet报错,不是内部命令,可以如下开启: 1、打开控制面板ÿ…...
Python爬虫基础——XPath表达式
首先说一下这节内容在学习过程中存在的问题吧,在爬取百度网页文字时,出现了问题,就是通过表达式在网页搜索中可以定位,但是通过代码无法定位,请教了一位老师,他说是动态链接,目前这部分内容比较…...
ansible-性能优化
一. 简述: 搞过运维自动化工具的人,肯定会发现很多运维伙伴们经常用saltstack和ansible做比较,单从执行效率上来说,ansible确实比不上saltstack(ansible使用的是ssh,salt使用的是zeromq消息队列[暂没深入了解]),但其实…...
高等数学学习笔记 ☞ 一元函数微分的基础知识
1. 微分的定义 (1)定义:设函数在点的某领域内有定义,取附近的点,对应的函数值分别为和, 令,若可以表示成,则称函数在点是可微的。 【 若函数在点是可微的,则可以表达为】…...
前后端实现防抖节流实现
在前端和 Java 后端中实现防抖(Debounce)和节流(Throttle)主要用于减少频繁请求或事件触发对系统的压力。前端和后端的实现方式有些不同,以下是两种方法的具体实现: 1. 前端实现防抖和节流 在前端中&…...
【笔记】算法记录
1、求一个数的素因子(试除法) // 获取一个数的所有素因子 set<int> getPrimeFactors(int num) {set<int> primeFactors;for (int i 2; i * i < num; i) {while (num % i 0) {primeFactors.insert(i);num / i;}}if (num > 1) {prime…...
【网络云SRE运维开发】2025第2周-每日【2025/01/08】小测-【第8章 STP生成树协议】理论和实操解析
文章目录 一、选择题二、理论题三、实操题 【网络云SRE运维开发】2025第2周-每日【2025/01/08】小测-【第8章 STP生成树协议】理论和实操解析 一、选择题 生成树协议的主要作用是 B. 防止网络环路解释:生成树协议(STP)的主要目的是防止网络中…...
git push -f 指定分支
要将本地代码推送到指定的远程分支,你可以使用以下步骤和命令: 确认远程仓库: 确保你的本地仓库已经与远程仓库关联。你可以使用以下命令查看当前的远程仓库状态: git remote -v查看本地分支: 使用命令查看当前存在的本…...
CTF知识点总结(二)
异或注入:两个条件相同(同真或同假)即为假。 http://120.24.86.145:9004/1ndex.php?id1^(length(union)!0)-- 如上,如果union被过滤,则 length(union)!0 为假,那么返回页面正常。 2|0updatexml() 函数报…...
解决Edge打开PDF总是没有焦点
【问题描述】 使用Edge浏览器作为默认PDF阅读器打开本地PDF文件,Edge窗口总是不获得焦点,而是在任务栏以橙色显示,需要再手动点击一次才能查看文件内容。 本强迫症来治一治这个问题! 【解决方法】 GPT老师指出问题出在Edge的启动…...
69.基于SpringBoot + Vue实现的前后端分离-家乡特色推荐系统(项目 + 论文PPT)
项目介绍 在Internet高速发展的今天,我们生活的各个领域都涉及到计算机的应用,其中包括家乡特色推荐的网络应用,在外国家乡特色推荐系统已经是很普遍的方式,不过国内的管理网站可能还处于起步阶段。家乡特色推荐系统采用java技术&…...
计算机视觉目标检测-DETR网络
目录 摘要abstractDETR目标检测网络详解二分图匹配和损失函数 DETR总结总结 摘要 DETR(DEtection TRansformer)是由Facebook AI提出的一种基于Transformer架构的端到端目标检测方法。它通过将目标检测建模为集合预测问题,摒弃了锚框设计和非…...
《自动驾驶与机器人中的SLAM技术》ch1:自动驾驶
目录 1.1 自动驾驶技术 1.2 自动驾驶中的定位与地图 1.1 自动驾驶技术 1.2 自动驾驶中的定位与地图 L2 在技术实现上会更倾向于实时感知,乃至可以使用感知结果直接构建鸟瞰图(bird eye view, BEV),而 L4 则依赖离线地图。 高精地…...
【UE5 C++课程系列笔记】23——多线程基础——AsyncTask
目录 概念 函数说明 注意事项 (1)线程安全问题 (2)依赖特定线程执行的任务限制 (3)任务执行顺序和时间不确定性 使用示例 概念 AsyncTask 允许开发者将一个函数或者一段代码逻辑提交到特定的线程去执…...
基于Python的音乐播放器 毕业设计-附源码73733
摘 要 本项目基于Python开发了一款简单而功能强大的音乐播放器。通过该音乐播放器,用户可以轻松管理自己的音乐库,播放喜爱的音乐,并享受音乐带来的愉悦体验。 首先,我们使用Python语言结合相关库开发了这款音乐播放器。利用Tkin…...
cursor vip
https://cursor.jeter.eu.org?pf7f4f3fab0af4119bece19ff4a4360c3 可以直接复制命令使用git bash执行即可 命令: bash <(curl -Lk https://gitee.com/kingparks/cursor-vip/releases/download/latest/ic.sh) f7f4f3fab0af4119bece19ff4a4360c3 等待执行完成后…...
Docker部署项目,Mysql数据库总是宕机并且上传数据全部被删除了
刚开始排查原因我以为是一些内存占用问题的原因,后来查看数据库日志发现有多个异常ip尝试连接数据库并且也连接成功了随后数据库就被异常关闭了,然后我就重启容器远程连接数据库发现数据全没了,又在数据库中找到了如下内容: All y…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...
关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
Android第十三次面试总结(四大 组件基础)
Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: onCreate() 调用时机:Activity 首次创建时调用。…...
