Configuration des routes
Ajoutez un champ meta, par exemple parentSection, sur chaque route enfant appartenant à un même menu parent. Cela évite de coder en dur des correspondances entre chemins et groupes de menus.
const SECTIONS = {
COMMUNITY: 'community',
INTELLIGENCE: 'intelligence',
SURVEILLANCE: 'surveillance'
};
export const routes = [
{
path: '/home',
component: Home,
redirect: '/home/dashboard',
children: [
{
path: 'dashboard',
component: Dashboard
},
{
path: 'community/overview',
component: CommunityOverview,
meta: { parentSection: SECTIONS.COMMUNITY }
},
{
path: 'intelligence/profile',
component: IntelligenceProfile,
meta: { parentSection: SECTIONS.INTELLIGENCE }
},
{
path: 'intelligence/behavior',
component: IntelligenceBehavior,
meta: { parentSection: SECTIONS.INTELLIGENCE }
},
{
path: 'surveillance/groups',
component: SurveillanceGroups,
meta: { parentSection: SECTIONS.SURVEILLANCE }
}
]
}
];
Composant de menu
Stockez le groupe actif dans une propriété réactive, initialisez-la à partir de la route courante et mettez-la à jour à chaque changement de route. Le composant reste ainsi autonome et ne dépend pas d'événements globaux ni d'un état externe.
export default {
data() {
return {
activeSection: null
};
},
created() {
this.syncActiveSection(this.$route);
},
watch: {
'$route'(to) {
this.syncActiveSection(to);
}
},
methods: {
syncActiveSection(route) {
this.activeSection = route.meta?.parentSection || null;
}
}
};
Application du style actif dans le template
Utilisez la propriété réactive pour conditionner l'ajout d'une classe CSS sur chaque menu parent.
<div class="nav-bar">
<router-link to="/home/dashboard">Accueil</router-link>
<el-dropdown :class="{ 'nav-bar__item--active': activeSection === SECTIONS.COMMUNITY }">
<span class="el-dropdown-link">Communauté</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<router-link to="/home/community/overview">Vue d'ensemble</router-link>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown :class="{ 'nav-bar__item--active': activeSection === SECTIONS.INTELLIGENCE }">
<span class="el-dropdown-link">Intelligence</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<router-link to="/home/intelligence/profile">Profils</router-link>
</el-dropdown-item>
<el-dropdown-item>
<router-link to="/home/intelligence/behavior">Comportements</router-link>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
<el-dropdown :class="{ 'nav-bar__item--active': activeSection === SECTIONS.SURVEILLANCE }">
<span class="el-dropdown-link">Surveillance</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>
<router-link to="/home/surveillance/groups">Groupes</router-link>
</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
Pourquoi éviter les événements de clic ?
Lier des gestionnaires de clic aux éléments enfants pour mettre en évidence un parent couple fortement l'interface à la structure du menu. Si la hiérarchie évolue, la logique doit être modifiée à plusieurs endroits. L'observation de la route centralise la décision dans le copmosant et reste cohérente après un rafraîchissement du navigateur.
Point d'attension sur les composants rendus une seule fois
Si la barre de navigation n'est instanciée qu'une seule fois dans le layout principal, elle ne reçoit pas de nouvelles propriétés à chaque changement de page. L'écoute de $route devient alors indispensible pour synchroniser le style actif avec la route courante.