Vue Router 与 Bootstrap 折叠导航栏冲突的解决方案

当在 `` 上同时使用 bootstrap 的 `data-bs-toggle` 和 `data-bs-target` 属性时,路由跳转失效且链接不可点击;根本原因是 bootstrap 的 collapse 插件会拦截原生点击事件并阻止默认行为,导致 vue router 的导航逻辑被中断。

在 Vue 3(或 Vue 2)项目中集成 Bootstrap 5 时,开发者常希望点击导航项既能触发 Vue Router 跳转,又能自动收起移动端折叠的导航栏(.navbar-collapse)。但直接将 data-bs-toggle="collapse" 和 data-bs-target=".navbar-collapse.show" 添加到 元素

上会导致链接失去响应——因为 Bootstrap 的 Collapse 插件在初始化时会为带 data-bs-toggle 的元素绑定 click 事件监听器,并调用 event.preventDefault(),从而阻断 内部的 标签默认跳转行为。

✅ 正确做法是解耦交互职责

  • 专注路由导航;
  • 收起导航栏交由 JavaScript 主动控制(而非依赖 data-bs-* 声明式行为)。

以下是优化后的 NavItem.vue 组件实现:



? 关键说明

  • 使用 @click="collapseNavbar" 替代 data-bs-toggle,确保点击时先执行收起逻辑,再由 自动完成导航(Vue Router 默认允许事件冒泡,且不阻止默认行为);
  • 通过 bootstrap.Collapse.getInstance() 复用已存在的实例,避免重复初始化;
  • :class="{ active: $route.name === router, [styles]: !!styles }" 修正了原始代码中 $router.name(应为 $route.name)及动态类名绑定语法;
  • 若项目未全局引入 Bootstrap JS,需确保 bootstrap 已正确安装(npm install bootstrap)并在入口文件中导入 CSS 与 JS(或按需导入)。

? 额外建议
对于更复杂的导航交互(如带下拉菜单),可进一步封装 useBootstrapCollapse() 组合式函数,提升复用性。同时,务必在 SPA 中监听路由变化后检查 .navbar-collapse.show 状态,避免页面跳转后导航栏仍处于展开态影响 UX。

该方案兼顾语义清晰、逻辑可控与框架兼容性,是 Vue + Bootstrap 混合开发中的推荐实践。