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

Bootstrap 5下拉事件在Vue.js 3项目中触发异常问题

Bootstrap 5下拉事件在Vue 3中仅初始化触发的问题解决

我发现Bootstrap 5的下拉事件在Vue.js 3应用中表现异常:应用内的下拉组件功能正常,但show.bs.dropdown/shown.bs.dropdown/hide.bs.dropdown/hidden.bs.dropdown事件仅在应用渲染时触发一次,切换或关闭下拉时完全不响应。而Vue应用外的原生JS版本下拉组件,事件则能按预期触发。

原代码对比

Vue 3应用内的HTML(有问题的写法)

<main>
    <div class="dropdown" id="dropdown1" v-on="{  'show.bs.dropdown': console.log('1'),'shown.bs.dropdown': console.log('2'),'hide.bs.dropdown': console.log('3'),'hidden.bs.dropdown': console.log('4') }">
        <button id="localeButton" class="btn btn-lg" type="button" data-bs-toggle="dropdown">
            <span>X</span>
        </button>
        <div class="dropdown-menu dropdown-menu-end" aria-labelledby="localeButton">
            <a class="dropdown-item" @click="a('A')">A</a>
            <a class="dropdown-item" @click="a('B')">B</a>
            <a class="dropdown-item" @click="a('C')">C</a>
            <a class="dropdown-item" @click="a('D')">D</a>
        </div>
    </div>
</main>

Vue 3应用代码

import { createApp } from 'vue'
createApp({
    data() {
        return {
            foo: 'X'
        }
    }, methods: {
        a(n) {
            this.foo = n
        }
    }
}).mount('main')

原生JS版本(正常工作)

HTML部分

<div class="dropdown" id="dropdown2">
    <button id="button2" class="btn btn-lg" type="button" data-bs-toggle="dropdown">
        <span>Y</span>
    </button>
    <div class="dropdown-menu dropdown-menu-end" aria-labelledby="button2">
        <a class="dropdown-item">Q</a>
        <a class="dropdown-item">W</a>
        <a class="dropdown-item">E</a>
        <a class="dropdown-item">R</a>
    </div>
</div>

JS部分

['show', 'shown', 'hide', 'hidden'].forEach(m => {
    document.getElementById('dropdown2').addEventListener(m + '.bs.dropdown', event => {
        console.log(m)
    })
})

问题原因

核心问题是Vue的v-on事件绑定语法错误:
直接写'show.bs.dropdown': console.log('1')时,console.log('1')会在Vue渲染模板时立即执行,而不是作为事件回调函数等待事件触发。此时绑定给事件的是console.log的返回值(undefined),所以后续事件触发时没有可执行的回调。

而原生JS中,我们传递的是一个箭头函数event => console.log(m),这个函数会在事件触发时才执行,所以能正常响应。

修复方案

把Vue事件绑定改成函数引用或箭头函数,确保回调在事件触发时才执行。

修复后的Vue模板(箭头函数写法)

<main>
    <div class="dropdown" id="dropdown1" v-on="{
        'show.bs.dropdown': () => console.log('1'),
        'shown.bs.dropdown': () => console.log('2'),
        'hide.bs.dropdown': () => console.log('3'),
        'hidden.bs.dropdown': () => console.log('4')
    }">
        <button id="localeButton" class="btn btn-lg" type="button" data-bs-toggle="dropdown">
            <span>{{ foo }}</span>
        </button>
        <div class="dropdown-menu dropdown-menu-end" aria-labelledby="localeButton">
            <a class="dropdown-item" @click="a('A')">A</a>
            <a class="dropdown-item" @click="a('B')">B</a>
            <a class="dropdown-item" @click="a('C')">C</a>
            <a class="dropdown-item" @click="a('D')">D</a>
        </div>
    </div>
</main>

或者提取到methods中(更易维护)

修改Vue应用代码

import { createApp } from 'vue'
createApp({
    data() {
        return {
            foo: 'X'
        }
    }, 
    methods: {
        a(n) {
            this.foo = n
        },
        handleDropdownShow() {
            console.log('1')
        },
        handleDropdownShown() {
            console.log('2')
        },
        handleDropdownHide() {
            console.log('3')
        },
        handleDropdownHidden() {
            console.log('4')
        }
    }
}).mount('main')

对应模板

<main>
    <div class="dropdown" id="dropdown1" v-on="{
        'show.bs.dropdown': handleDropdownShow,
        'shown.bs.dropdown': handleDropdownShown,
        'hide.bs.dropdown': handleDropdownHide,
        'hidden.bs.dropdown': handleDropdownHidden
    }">
        <!-- 其余内容不变 -->
    </div>
</main>

验证效果

修复后,点击下拉按钮展开/收起时,控制台会依次输出对应的日志,和原生JS版本的行为一致。

内容的提问来源于stack exchange,提问作者Linus Yip

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 23:20:13