Vue3+Laravel9环境下Flowbite组件交互失效问题求助
Flowbite Vue组件交互失效排查(Vue3+Tailwind3+Laravel9)
问题现象
- 手风琴组件无法打开/关闭,始终处于打开状态
- 模态框无法关闭,轮播组件无法切换幻灯片
手风琴代码示例
<template> <div id="accordion-arrow-icon" data-accordion="open"> <h2 id="accordion-arrow-icon-heading-1"> <button type="button" class="flex items-center justify-between w-full p-5 font-medium text-left text-gray-900 bg-gray-100 border border-b-0 border-gray-200 rounded-t-xl focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:border-gray-700 dark:text-white dark:bg-gray-800 hover:bg-gray-100 dark:hover:bg-gray-800" data-accordion-target="#accordion-arrow-icon-body-1" aria-expanded="true" aria-controls="accordion-arrow-icon-body-1"> <span>Accordion without an arrow</span> </button> </h2> <div id="accordion-arrow-icon-body-1" aria-labelledby="accordion-arrow-icon-heading-1"> <div class="p-5 font-light border border-b-0 border-gray-200 dark:border-gray-700 dark:bg-gray-900"> <p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is an open-source library of interactive components built on top of Tailwind CSS including buttons, dropdowns, modals, navbars, and more.</p> <p class="text-gray-500 dark:text-gray-400">Check out this guide to learn how to <a href="/docs/getting-started/introduction/" class="text-blue-600 dark:text-blue-500 hover:underline">get started</a> and start developing websites even faster with components on top of Tailwind CSS.</p> </div> </div> <h2 id="accordion-arrow-icon-heading-2"> <button type="button" class="flex items-center justify-between w-full p-5 font-medium text-left text-gray-500 border border-b-0 border-gray-200 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800" data-accordion-target="#accordion-arrow-icon-body-2" aria-expanded="false" aria-controls="accordion-arrow-icon-body-2"> <span>Accordion with another icon</span> <svg data-accordion-icon class="w-6 h-6 shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 13l-3 3m0 0l-3-3m3 3V8m0 13a9 9 0 110-18 9 9 0 010 18z"></path></svg> </button> </h2> <div id="accordion-arrow-icon-body-2" class="hidden" aria-labelledby="accordion-arrow-icon-heading-2"> <div class="p-5 font-light border border-b-0 border-gray-200 dark:border-gray-700"> <p class="mb-2 text-gray-500 dark:text-gray-400">Flowbite is first conceptualized and designed using the Figma software so everything you see in the library has a design equivalent in our Figma file.</p> <p class="text-gray-500 dark:text-gray-400">Check out the <a href="https://flowbite.com/figma/" class="text-blue-600 dark:text-blue-500 hover:underline">Figma design system</a> based on the utility classes from Tailwind CSS and components from Flowbite.</p> </div> </div> <h2 id="accordion-arrow-icon-heading-3"> <button type="button" class="flex items-center justify-between w-full p-5 font-medium text-left text-gray-500 border border-gray-200 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800" data-accordion-target="#accordion-arrow-icon-body-3" aria-expanded="false" aria-controls="accordion-arrow-icon-body-3"> <span>Accordion without arrow rotation</span> <svg class="w-6 h-6 shrink-0" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd"></path></svg> </button> </h2> <div id="accordion-arrow-icon-body-3" class="hidden" aria-labelledby="accordion-arrow-icon-heading-3"> <div class="p-5 font-light border border-t-0 border-gray-200 dark:border-gray-700"> <p class="mb-2 text-gray-500 dark:text-gray-400">The main difference is that the core components from Flowbite are open source under the MIT license, whereas Tailwind UI is a paid product. Another difference is that Flowbite relies on smaller and standalone components, whereas Tailwind UI offers sections of pages.</p> <p class="mb-2 text-gray-500 dark:text-gray-400">However, we actually recommend using both Flowbite, Flowbite Pro, and even Tailwind UI as there is no technical reason stopping you from using the best of two worlds.</p> <p class="mb-2 text-gray-500 dark:text-gray-400">Learn more about these technologies:</p> <ul class="pl-5 text-gray-500 list-disc dark:text-gray-400"> <li><a href="https://flowbite.com/pro/" class="text-blue-600 dark:text-blue-500 hover:underline">Flowbite Pro</a></li> <li><a href="https://tailwindui.com/" rel="nofollow" class="text-blue-600 dark:text-blue-500 hover:underline">Tailwind UI</a></li> </ul> </div> </div> </div> </template>
原JavaScript代码
// create an array of objects with the id, trigger element (eg. button), and the content element const accordionItems = [ { id: 'accordion-example-heading-1', triggerEl: document.querySelector('#accordion-example-heading-1'), targetEl: document.querySelector('#accordion-example-body-1'), active: true }, { id: 'accordion-example-heading-2', triggerEl: document.querySelector('#accordion-example-heading-2'), targetEl: document.querySelector('#accordion-example-body-2'), active: false }, { id: 'accordion-example-heading-3', triggerEl: document.querySelector('#accordion-example-heading-3'), targetEl: document.querySelector('#accordion-example-body-3'), active: false } ]; // options with default values const options = { alwaysOpen: true, activeClasses: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white', inactiveClasses: 'text-gray-500 dark:text-gray-400', onOpen: (item) => { console.log('accordion item has been shown'); console.log(item); }, onClose: (item) => { console.log('accordion item has been hidden'); console.log(item); }, onToggle: (item) => { console.log('accordion item has been toggled'); console.log(item); }, };
核心问题与修复方案
1. 修正ID匹配错误
原JS代码中的ID与模板中的ID完全不匹配(模板用accordion-arrow-icon-*,JS用accordion-example-*),导致无法找到目标DOM元素。修正后的JS数组:
const accordionItems = [ { id: 'accordion-arrow-icon-heading-1', triggerEl: document.querySelector('#accordion-arrow-icon-heading-1 button'), targetEl: document.querySelector('#accordion-arrow-icon-body-1'), active: true }, { id: 'accordion-arrow-icon-heading-2', triggerEl: document.querySelector('#accordion-arrow-icon-heading-2 button'), targetEl: document.querySelector('#accordion-arrow-icon-body-2'), active: false }, { id: 'accordion-arrow-icon-heading-3', triggerEl: document.querySelector('#accordion-arrow-icon-heading-3 button'), targetEl: document.querySelector('#accordion-arrow-icon-body-3'), active: false } ];
2. 在Vue生命周期钩子中初始化组件
Vue组件DOM在mounted阶段才完全渲染完成,必须将初始化代码放在mounted中,确保能获取到DOM元素:
<template> <!-- 手风琴模板代码 --> </template> <script setup> import { onMounted } from 'vue'; import { Accordion } from 'flowbite'; onMounted(() => { // 修正后的accordionItems数组 const accordionItems = [ { id: 'accordion-arrow-icon-heading-1', triggerEl: document.querySelector('#accordion-arrow-icon-heading-1 button'), targetEl: document.querySelector('#accordion-arrow-icon-body-1'), active: true }, { id: 'accordion-arrow-icon-heading-2', triggerEl: document.querySelector('#accordion-arrow-icon-heading-2 button'), targetEl: document.querySelector('#accordion-arrow-icon-body-2'), active: false }, { id: 'accordion-arrow-icon-heading-3', triggerEl: document.querySelector('#accordion-arrow-icon-heading-3 button'), targetEl: document.querySelector('#accordion-arrow-icon-body-3'), active: false } ]; const options = { alwaysOpen: true, activeClasses: 'bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white', inactiveClasses: 'text-gray-500 dark:text-gray-400', onOpen: (item) => { console.log('accordion item has been shown'); console.log(item); }, onClose: (item) => { console.log('accordion item has been hidden'); console.log(item); }, onToggle: (item) => { console.log('accordion item has been toggled'); console.log(item); }, }; // 初始化手风琴 new Accordion(accordionItems, options); }); </script>
3. 优先使用Flowbite Vue组件(更简洁)
如果安装的是Flowbite Vue组件库,直接使用封装好的Vue组件可自动绑定交互:
<template> <Accordion> <AccordionPanel> <AccordionHeader>Accordion without an arrow</AccordionHeader> <AccordionBody> <p class="mb-2 text-gray-500 dark:text-gray-400"> Flowbite是基于Tailwind CSS构建的开源交互组件库,包含按钮、下拉菜单、模态框、导航栏等。 </p> <p class="text-gray-500 dark:text-gray-400"> 查看指南了解如何快速开始,基于Tailwind CSS组件更快开发网站。 </p> </AccordionBody> </AccordionPanel> <!-- 其他面板重复上述结构 --> </Accordion> </template> <script setup> import { Accordion, AccordionPanel, AccordionHeader, AccordionBody } from '@flowbite/vue'; </script>
4. 全局初始化Flowbite(可选)
若项目中有大量Flowbite组件,可在main.js中全局注册:
import { createApp } from 'vue'; import App from './App.vue'; import Flowbite from 'flowbite'; const app = createApp(App); app.use(Flowbite); app.mount('#app');
内容的提问来源于stack exchange,提问作者Sham
相关产品推荐
相关产品推荐

