在做项目时,如果我们点击导航栏时需要实现如下效果:
- 比如点击 前端导航,浏览器显示地址为
http://xxxxxxx:8080/#/?category=front-end - 点击 java导航,浏览器显示地址为
http://xxxxxxx:8080/#/?category=java - 当点击首页时,导航栏高亮消失,并且浏览器地址回归到
http://xxxxxxx:8080/#/
要实现以上途中的效果其实很简单,具体代码如下: src/components/NavMenu.vue
<template>
<el-menu class="menu" :default-active="activeMenu" mode="horizontal" @select="handleMenuSelect">
<el-menu-item index="front-end">前端</el-menu-item>
<el-menu-item index="java">Java</el-menu-item>
<el-menu-item index="python">Python</el-menu-item>
<el-menu-item index="mini-program">小程序</el-menu-item>
</el-menu>
</template>
<script setup>
import { watch, ref } from 'vue';
import { useRoute, useRouter } from 'vue-router';
const router = useRouter();
const route = useRoute();
const activeMenu = ref('')
// 监听 route.query.category 实时更新 activeMenu
watch(() => route.query.category, val => {
activeMenu.value = val
})
const handleMenuSelect = (index) => {
router.push({
path: '/', query: { category: index }
})
}
</script>
<style lang="scss" scoped>
.menu {
background-color: #f5f5f5;
}
</style>
说明:
watch的目的是监听route.query.category这个路由查询参数的变化。当用户通过路由切换页面或手动修改路由的查询参数category时,watch会检测到变化并执行回调函数。在这里,它的作用是将val(category的新值)赋给activeMenu变量,以实时更新当前激活的菜单项。handleMenuSelect是一个自定义的函数,用于处理菜单项的选择事件。它接受一个参数index,该参数表示被选中菜单项的索引。在函数内部,它使用router.push来更新路由的查询参数,将选中的菜单项的索引作为category的新值。这个函数在菜单项被选择时触发,通常是用户点击了一个菜单项。通过调用router.push,它会改变当前路由的查询参数,以便更新页面内容或触发其他与路由相关的操作。
App.vue
<template>
<div class="top-navbar">
<div class="left-section">
<div class="logo">
<router-link to="/">
<h1>TechBlog</h1>
</router-link>
</div>
<NavMenu class="nav-menu"></NavMenu>
</div>
<div class="right-section">
<router-link class="login-link" to="/login">登录</router-link>
</div>
</div>
<div class="main-content">
<div class="container">
<router-view />
</div>
</div>
</template>
<script setup>
import NavMenu from '@/components/NavMenu.vue';
</script>
<style lang="scss" scoped>
.top-navbar {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 60px;
background-color: #f5f5f5;
padding: 0 20px;
box-sizing: border-box;
border-bottom: 1px solid var(--el-menu-border-color);
}
.left-section {
display: flex;
align-items: center;
}
.nav-menu {
border-bottom: none !important;
margin-left: 20px;
}
.logo {
height: 40px;
}
.logo a {
text-decoration: none;
}
.right-section a {
text-decoration: none;
}
.main-content {
width: 100%;
padding: 20px;
box-sizing: border-box;
}
.container {
max-width: 1000px;
margin: 0 auto;
}
</style>