Vue搭配Bootstrap data-toggle阻止事件冒泡时a标签href仍触发如何解决
问题根因
你错误地将仅适用于v-on(事件绑定)的.stop修饰符用在了v-bind(属性绑定)指令上,v-bind本身不处理任何事件逻辑,加的修饰符完全不会生效,点击小箭头的事件会正常冒泡到外层的a标签,触发href跳转逻辑。
符合Vue开发规范的解决方案
核心思路是完全采用Vue响应式数据驱动状态,移除jQuery DOM操作,不依赖Bootstrap原生的data-toggle折叠逻辑:
<template> <ul class="nav navbar-nav"> <li v-for="(item, i) in items" :class="classes(item)" :key="item.id"> <a :target="item.target" :href="item.href" :style="'color:'+color(item)"> <span v-if="item.icon_class" :class="'icon '+item.icon_class"></span> <span class="title">{{ item.title }}</span> <span v-if="item.children.length > 0" :class="[ 'icon-toggle', item.active ? 'voyager-angle-down' : 'voyager-angle-right' ]" @click.stop.prevent="toggleCollapse(item)" :aria-expanded="String(item.active)" ></span> </a> <div v-if="item.children.length > 0" :id="item.id+'-dropdown-element'" :class="[ 'panel-collapse collapse', item.active ? 'in' : '' ]" > <div class="panel-body"> <admin-menu :items="item.children"></admin-menu> </div> </div> </li> </ul> </template> <script> export default { props: { items: { type: Array, default: () => [], } }, methods: { classes(item) { const classes = []; if (item.children.length > 0) { classes.push('dropdown'); } if (item.active) { classes.push('active'); } return classes.join(' '); }, color(item) { if (item.color && item.color != '#000000') { return item.color; } return ''; }, toggleCollapse(currentItem) { // 先把同层级所有菜单的展开状态重置 this.items.forEach(item => { if (item.id !== currentItem.id) { item.active = false; } }); // 切换当前点击菜单的展开状态 currentItem.active = !currentItem.active; } } }; </script>
方案说明
- 事件修饰符
.stop.prevent正确绑定在点击事件上,直接阻止事件冒泡到外层a标签,也阻止默认点击行为,从根源避免跳转问题 - 所有展开收起、样式切换完全通过响应式的
item.active属性控制,没有任何手动DOM操作,符合Vue数据驱动的开发规范 - 移除了对Bootstrap原生折叠逻辑和jQuery的依赖,组件可维护性和兼容性更高
内容的提问来源于stack exchange,提问作者John Magnolia
相关产品推荐
相关产品推荐

