
本文详解如何在 vuetify 2.x 中为侧边菜单的 `v-list-item` 实现点击态高亮,通过 `active-class` 属性与路由/状态联动,避免为每个菜单项单独声明布尔变量,提升代码可维护性与扩展性。
在构建基于 Vuetify 的单页应用(SPA)时,侧边导航菜单(如 v-list + v-list-group)常需响应式高亮当前选中项。若采用手动维护多个 isXXXActive 布尔状态(如 isMainWifiActive, isGuestWifiActive),不仅冗余繁琐,更违背响应式开发原则——理想方案应复用单一状态源,并由组件自动判断激活关系。
Vuetify 2.x 原生提供了优雅解法:v-list-group 支持 active-class prop,而 v-list-item 支持 value 和 to(或配合 @click 手动更新)协同工作,实现自动激活样式绑定。
✅ 推荐实践:使用 value + active-class + 单一状态管理
核心思路是:
- 用一个响应式数据(如 selectedMenuItem)统一记录当前激活项的唯一标识(字符串或 ID);
- 每个 v-list-item 设置 :value="itemKey"(如 'Main Wi-Fi');
- v-list-group 设置 active-class="list-item--active",并确保其 value 绑定到 selectedMenuItem;
- 点击时调用 menu_change(key) 更新 selectedMenuItem,Vuetify 自动匹配并添加高亮类。
示例代码(精简可复用结构)
<template>
<v-list dense nav>
<v-list-group
sub-group
:value="selectedMenuItem" <!-- 关键:绑定到统一状态 -->
active-class="list-item--active" <!-- 自定义高亮类 -->
>
<template v-slot:activator>
<v-list-item-content>
<v-list-item-title>General settings</v-list-item-title>
</v-list-item-content>
</template>
<!-- Main Wi-Fi 项 -->
<v-list-item
v-if="isModelFX20 || isModelRG21"
value="Main Wi-Fi" <!-- 唯一标识,供自动匹配 -->
@click="menu_change('Main Wi-Fi')"
>
<v-list-item-title>Main Wi-Fi</v-list-item-title>
</v-list-item>
<!-- Guest Wi-Fi 项 -->
<v-list-item
v-if="isModelFX20 || isModelRG21"
value="Guest Wi-Fi"
@click="menu_change('Guest Wi-Fi')"
>
<v-list-item-title>Guest Wi-Fi</v-list-item-title>
</v-list-item>
</v-list-group>
</v-list>
</template>
<script>
export default {
data() {
return {
selectedMenuItem: 'Main Wi-Fi', // 初始高亮项
// 其他数据...
}
},
computed: {
isModelFX20() {
const { router_model, group_model } = this.routerDetail
return router_model === 'FX20' || group_model === 'FX20'
},
isModelRG21() {
const { router_model, group_model } = this.routerDetail
return ['RG21'].some(prefix =>
router_model.startsWith(prefix) || group_model.startsWith(prefix)
)
}
},
methods: {
menu_change(key) {
this.selectedMenuItem = key // 单一赋值,驱动所有项重渲染
// 可选:触发路由跳转或页面逻辑
this.$emit('menu-change', key)
}
}
}
</script>
<style scoped>
/* 自定义高亮样式(作用于 .list-item--active) */
.list-item--active {
background-color: rgba(0, 0, 0, 0.04) !important;
border-left: 4px solid #1976D2;
}
/* 为文字添加强调色(可选) */
.list-item--active .v-list-item__title {
color: #1976D2 !important;
font-weight: 500;
}
</style>⚠️ 注意事项与最佳实践
- value 必须唯一且稳定:建议使用语义化字符串(如 'Main Wi-Fi'),避免动态拼接或计算属性返回不稳定值,否则激活匹配会失效。
- v-list-group 是关键容器:active-class 仅在 v-list-group 上生效,且依赖其 value 与子 v-list-item 的 value 匹配;独立 v-list-item 不支持该机制。
- 避免 :class 手动绑定冲突:若同时使用 :class="{active: xxx}" 和 active-class,可能造成样式覆盖或重复渲染,推荐统一使用 active-class 方案。
- 配合 Vue Router 更进一步:若菜单与路由深度耦合,可将 value 设为 route.name 或 route.path,并通过 watch: { $route } 自动同步 selectedMenuItem,实现路由驱动高亮。
✅ 总结
无需为每个菜单项创建独立状态变量,也不必手动维护繁杂的条件类绑定。利用 Vuetify 2.x 内置的 v-list-group 的 active-class 与 value 双向绑定机制,仅需一个 selectedMenuItem 数据字段,即可实现清晰、可扩展、低耦合的菜单高亮逻辑。这既是框架能力的合理运用,也是 Vue 响应式设计哲学的典型体现。
立即学习“前端免费学习笔记(深入)”;










