Vue中实现点击侧边子菜单v-list-item高亮的方法
侧边菜单高亮优化方案
问题说明
我有一个随路由器型号动态变化的侧边菜单,需要实现点击页面时对应子菜单高亮(点击后对应菜单项呈现选中样式)。当前菜单为层级结构,包含分组和子菜单项,现有子菜单代码如下:
现有子菜单代码
<v-list-group sub-group :value="true"> <template v-slot:activator> <v-list-item-content> <v-list-item-title>General settings</v-list-item-title> </v-list-item-content> </template> <v-list-item v-if=" (Router_Obj.is_individual_router == true || Router_Obj.is_individual_router == false) && (routerDetail.router_model == 'FX20' || routerDetail.group_model == 'FX20') " value="true" @click="menu_change('Main Wi-Fi')" > <v-list-item-title>Main Wi-Fi</v-list-item-title> </v-list-item> <v-list-item v-if=" routerDetail.router_model.substring(0, 4) == 'RG21' || routerDetail.group_model.substring(0, 4) == 'RG21' " @click="menu_change('Main Wi-Fi')" > <v-list-item-title>Main Wi-Fi</v-list-item-title> </v-list-item> <v-list-item v-if=" (Router_Obj.is_individual_router == true || Router_Obj.is_individual_router == false) && (routerDetail.router_model == 'FX20' || routerDetail.group_model == 'FX20') " @click="menu_change('Guest Wi-Fi')" > <v-list-item-title>Guest Wi-Fi</v-list-item-title> </v-list-item> <v-list-item v-if=" routerDetail.router_model.substring(0, 4) == 'RG21' || routerDetail.group_model.substring(0, 4) == 'RG21' " @click="menu_change('Guest Wi-Fi')" > <v-list-item-title>Guest Wi-Fi</v-list-item-title> </v-list-item> </v-list-group>
现有尝试与困惑
我尝试通过类绑定实现高亮,但不想给每个子菜单单独定义isMainWifiActive这类变量,操作繁琐。目前已按照建议用openMenu变量跟踪当前页面,通过条件类绑定实现高亮,示例代码如下:
<v-list-item v-if=" routerDetail.router_model.substring(0, 4) == 'RG21' || routerDetail.group_model.substring(0, 4) == 'RG21' " :class="{'active': openMenu == 'Main Wi-Fi'}" @click="menu_change('Main Wi-Fi')" > <v-list-item-title>Main Wi-Fi</v-list-item-title> </v-list-item>
简洁优化方案
可以通过结构化菜单数据+循环渲染的方式,彻底简化代码并统一高亮逻辑:
1. 定义结构化菜单数据
在组件的data中整理菜单信息,同时将重复的型号判断抽离为计算属性:
data() { return { openMenu: '', // 统一管理菜单数据 menuItems: [ { name: 'Main Wi-Fi' }, { name: 'Guest Wi-Fi' } ] } }, computed: { isFX20Model() { // 简化冗余的布尔判断(true/false都满足可直接省略) return this.routerDetail.router_model === 'FX20' || this.routerDetail.group_model === 'FX20' }, isRG21Model() { return this.routerDetail.router_model.substring(0, 4) === 'RG21' || this.routerDetail.group_model.substring(0, 4) === 'RG21' } }
2. 循环渲染子菜单
模板中通过v-for渲染所有子菜单,统一处理显示条件和高亮绑定:
<v-list-group sub-group :value="true"> <template v-slot:activator> <v-list-item-content> <v-list-item-title>General settings</v-list-item-title> </v-list-item-content> </template> <!-- 循环渲染所有菜单项 --> <v-list-item v-for="item in menuItems" :key="item.name" <!-- 统一判断显示条件 --> v-if="isFX20Model || isRG21Model" <!-- 统一高亮绑定 --> :class="{ 'active': openMenu === item.name }" @click="menu_change(item.name)" > <v-list-item-title>{{ item.name }}</v-list-item-title> </v-list-item> </v-list-group>
方案优势
- 避免重复代码:新增菜单项只需在
menuItems数组中添加,无需重复编写v-list-item标签 - 逻辑统一:显示条件和高亮逻辑集中处理,后续维护更便捷
- 变量精简:仅用
openMenu一个变量跟踪当前激活状态,无需为每个菜单项单独定义状态变量
内容的提问来源于stack exchange,提问作者Gene Lee
相关产品推荐
相关产品推荐

