欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 页面顶部导航栏(Navbar)的功能(Navbar/index.vue)

页面顶部导航栏(Navbar)的功能(Navbar/index.vue)

2025/6/8 16:52:42 来源:https://blog.csdn.net/m0_65152767/article/details/144992005  浏览:    关键词:页面顶部导航栏(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": 判断用户是否有头像, 如果有头像,则拼接ossavatar 作为头像的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-blockvertical-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-blockvertical-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>

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词