Vue Router <router-link>与Bootstrap data-bs属性冲突致无法点击
解决router-link与Bootstrap折叠属性冲突导致路由不跳转的问题
问题根源是Bootstrap的data-bs-toggle和data-bs-target会拦截router-link的点击事件,阻止默认的跳转行为,所以两者同时使用时路由无法触发。下面提供两种可行的解决方法:
方法一:手动处理点击事件,兼顾折叠与路由跳转
保留Bootstrap的折叠逻辑,但手动触发路由跳转,同时确保折叠效果正常:
修改你的NavItem组件:
<template> <li class="nav-item"> <router-link class="nav-link py-2 px-md-2" :to="{ name: router }" :class="{active: $router.name === router, styles}" @click="handleNavClick" > <slot /> </router-link> </li> </template> <script> export default { name: 'NavItem', props: { router: { type: String, required: true, }, styles: { type: String, required: true, }, }, methods: { handleNavClick(e) { // 手动触发Bootstrap折叠效果 const collapseEl = document.querySelector('.navbar-collapse.show'); if (collapseEl) { const collapse = new window.bootstrap.Collapse(collapseEl, { toggle: true }); collapse.hide(); } // 手动执行路由跳转 this.$router.push({ name: this.router }); // 阻止默认事件避免冲突 e.preventDefault(); } } }; </script>
注意:确保你的项目已经全局引入了Bootstrap的JS文件,否则需要单独导入Collapse模块。
方法二:用Vue响应式状态控制折叠(更推荐)
放弃Bootstrap的data-*属性,改用Vue的响应式数据控制折叠状态,更符合Vue的开发思路,也避免DOM操作:
1. 父组件(导航栏所在组件)
<template> <nav class="navbar navbar-expand-lg"> <!-- 折叠按钮 --> <button class="navbar-toggler" type="button" @click="isCollapseOpen = !isCollapseOpen"> <span class="navbar-toggler-icon"></span> </button> <!-- 折叠菜单 --> <div class="navbar-collapse" :class="{ show: isCollapseOpen }"> <ul class="navbar-nav"> <NavItem router="home" styles="..." @close-collapse="isCollapseOpen = false" >首页</NavItem> <NavItem router="about" styles="..." @close-collapse="isCollapseOpen = false" >关于我们</NavItem> </ul> </div> </nav> </template> <script> import NavItem from './NavItem.vue'; export default { components: { NavItem }, data() { return { isCollapseOpen: false }; } }; </script>
2. 修改后的NavItem组件
<template> <li class="nav-item"> <router-link class="nav-link py-2 px-md-2" :to="{ name: router }" :class="{active: $router.name === router, styles}" @click="$emit('close-collapse')" > <slot /> </router-link> </li> </template> <script> export default { name: 'NavItem', props: { router: { type: String, required: true, }, styles: { type: String, required: true, }, }, }; </script>
这种方式通过Vue的事件传递和响应式状态控制折叠,完全避免了事件冲突,代码也更易维护。
内容的提问来源于stack exchange,提问作者Bro From Space
相关产品推荐
相关产品推荐

