Vue RouterLink结合v-for如何修改current属性实现菜单高亮?
问题
我使用以下代码实现侧边栏导航:
<router-link v-for="item in navigation" :key="item.name" :to="item.to" @click="(item.current = true)" :class="[ item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'group flex items-center px-2 py-2 text-base font-medium rounded-md', ]" > <!-- 导航内容 --> </router-link>
const navigation = [ { name: "Dashboard", to: "/", icon: HomeIcon, current: false }, { name: "About", to: "/about", icon: UsersIcon, current: false }, { name: "Projects", to: "/about", icon: FolderIcon, current: false }, ];
我的问题是:如何结合RouterLink实现点击对应菜单项时,将其current属性设为true,从而切换Tailwind样式类?我尝试直接写(item.current = true),但会把所有项的current都改为true。目前我用active-class实现了效果,但想了解正确的实现方式。
正确实现方式
1. 点击事件手动控制激活状态
直接修改单个item.current不会重置其他项的状态,导致所有项都显示激活样式。需要编写处理函数,先统一重置所有项的current,再单独激活当前点击项:
修改JavaScript部分,添加状态控制函数:
// 用ref包裹数组确保响应式 const navigation = ref([ { name: "Dashboard", to: "/", icon: HomeIcon, current: false }, { name: "About", to: "/about", icon: UsersIcon, current: false }, { name: "Projects", to: "/projects", icon: FolderIcon, current: false }, ]); const setActiveNav = (selectedItem) => { navigation.value.forEach(item => { item.current = item === selectedItem; }); };
更新HTML中的点击事件绑定:
<router-link v-for="item in navigation" :key="item.name" :to="item.to" @click="setActiveNav(item)" :class="[ item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'group flex items-center px-2 py-2 text-base font-medium rounded-md', ]" > <!-- 导航内容 --> </router-link>
2. 结合路由自动匹配(更优雅方案)
利用Vue Router的路由监听功能,自动匹配当前路由对应的导航项,无需手动处理点击事件:
import { useRoute, watch } from 'vue-router'; const route = useRoute(); const navigation = ref([ { name: "Dashboard", to: "/", icon: HomeIcon, current: false }, { name: "About", to: "/about", icon: UsersIcon, current: false }, { name: "Projects", to: "/projects", icon: FolderIcon, current: false }, ]); // 匹配当前路由对应的导航项 const matchActiveNav = () => { navigation.value.forEach(item => { item.current = route.path === item.to; }); }; // 监听路由变化,自动更新激活状态 watch(() => route.path, matchActiveNav); // 页面初始化时执行一次匹配 matchActiveNav();
此时HTML可移除@click绑定:
<router-link v-for="item in navigation" :key="item.name" :to="item.to" :class="[ item.current ? 'bg-gray-900 text-white' : 'text-gray-300 hover:bg-gray-700 hover:text-white', 'group flex items-center px-2 py-2 text-base font-medium rounded-md', ]" > <!-- 导航内容 --> </router-link>
内容的提问来源于stack exchange,提问作者funkyj4ever
相关产品推荐
相关产品推荐

