You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt.js单页应用菜单高亮脚本路由导航时失效求助

问题分析

直接访问页面时代码生效是因为页面会完整加载,代码执行一次;但SPA路由跳转是客户端无刷新切换,原代码仅在页面首次加载时运行,路由切换后不会重新触发,所以菜单高亮失效。即使切换到Universal模式,客户端路由跳转时也不会重新执行初始加载的代码,因此问题无法解决。

解决方案

推荐三种可行方案,按优雅度排序:

方案1:响应式动态绑定(最推荐)

无需手动操作DOM,利用Nuxt的路由响应式特性直接绑定状态:

<template>
  <nav>
    <a 
      class="accueil" 
      href="/"
      :id="route.path === '/' ? 'active' : null"
    >Accueil</a>
    <a 
      class="tous-les-articles" 
      href="/tous-les-articles"
      :id="route.path === '/tous-les-articles' ? 'active' : null"
    >Tous les articles</a>
    <a 
      class="sciences" 
      href="/sciences"
      :id="route.path === '/sciences' ? 'active' : null"
    >Sciences</a>
    <a 
      class="actualites" 
      href="/actualites"
      :id="route.path === '/actualites' ? 'active' : null"
    >Actualités</a>
    <a 
      class="histoire" 
      href="/histoire"
      :id="route.path === '/histoire' ? 'active' : null"
    >Histoire</a>
    <a 
      class="livres" 
      href="/livres"
      :id="route.path === '/livres' ? 'active' : null"
    >Livres</a>
    <a 
      class="le-saviez-vous" 
      href="/le-saviez-vous"
      :id="route.path === '/le-saviez-vous' ? 'active' : null"
    >Le saviez-vous?</a>
  </nav>
  <nuxt />
</template>

<script setup>
import { useRoute } from 'vue-router';
const route = useRoute();
</script>

路由切换时,route.path会自动更新,绑定的id也会同步变化,完全符合Vue响应式逻辑。

方案2:布局组件监听路由变化

在全局布局文件(如layouts/default.vue)中监听路由切换,触发菜单状态更新:

<template>
  <nav>
    <!-- 菜单结构保持不变 -->
    <a class="accueil" href="/">Accueil</a>
    <a class="tous-les-articles" href="/tous-les-articles">Tous les articles</a>
    <!-- 其他菜单项 -->
  </nav>
  <nuxt />
</template>

<script setup>
import { watch, onMounted } from 'vue';
import { useRoute } from 'vue-router';

const route = useRoute();

const updateActiveMenu = () => {
  // 先清除所有已激活的菜单id
  document.querySelectorAll('#active').forEach(el => el.removeAttribute('id'));
  
  // 路由路径与菜单类名映射
  const pathMap = {
    '/': 'accueil',
    '/tous-les-articles': 'tous-les-articles',
    '/sciences': 'sciences',
    '/actualites': 'actualites',
    '/histoire': 'histoire',
    '/livres': 'livres',
    '/le-saviez-vous': 'le-saviez-vous'
  };

  const targetClass = pathMap[route.path];
  if (targetClass) {
    const menuItem = document.querySelector(`.${targetClass}`);
    if (menuItem) menuItem.setAttribute('id', 'active');
  }
};

// 页面首次加载时执行
onMounted(updateActiveMenu);
// 监听路由变化,每次切换都更新
watch(() => route.path, updateActiveMenu);
</script>

方案3:全局路由中间件

创建全局中间件,每次路由切换时执行菜单更新逻辑:

  1. 在项目根目录创建middleware/activeMenu.js:
export default function ({ route }) {
  // 确保仅在客户端执行(服务端无DOM)
  if (process.client) {
    // 清除所有激活状态
    document.querySelectorAll('#active').forEach(el => el.removeAttribute('id'));
    
    const pathMap = {
      '/': 'accueil',
      '/tous-les-articles': 'tous-les-articles',
      '/sciences': 'sciences',
      '/actualites': 'actualites',
      '/histoire': 'histoire',
      '/livres': 'livres',
      '/le-saviez-vous': 'le-saviez-vous'
    };

    const targetClass = pathMap[route.path];
    if (targetClass) {
      const menuItem = document.querySelector(`.${targetClass}`);
      if (menuItem) menuItem.setAttribute('id', 'active');
    }
  }
}
  1. 在nuxt.config.js中注册全局中间件:
export default {
  router: {
    middleware: ['activeMenu']
  }
}

内容的提问来源于stack exchange,提问作者MH info

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 16:00:27