Next.js项目中Tailwind CSS的data-dropdown-toggle无法打开user-dropdown
解决Next.js中Flowbite导航栏用户下拉菜单不展开的问题
你的问题核心是未加载Flowbite的交互JavaScript,原生Flowbite的下拉菜单依赖自身JS处理data-dropdown-toggle这类属性的点击事件;另外在Next.js这类React框架中直接用原生HTML结构,还可能遇到 hydration 不匹配的问题。下面提供两种可行的解决方式:
方式一:引入Flowbite原生JS(快速适配现有代码)
- 先安装Flowbite依赖:
npm install flowbite
- 选择以下一种方式加载JS:
- 全局引入(推荐):在根布局文件(如
app/layout.js)中添加脚本:import Script from 'next/script'; export default function RootLayout({ children }) { return ( <html lang="en"> <body> {children} <Script src="https://cdn.jsdelivr.net/npm/flowbite@2.5.1/dist/flowbite.min.js" strategy="lazyOnload" /> </body> </html> ); } - 组件内动态初始化:在NavBar组件中添加初始化逻辑:
import { useEffect } from 'react'; const NavBar = () => { useEffect(() => { import('flowbite').then(module => { module.initDropdowns(); }); }, []); // 你的原有JSX代码... }
- 全局引入(推荐):在根布局文件(如
方式二:使用Flowbite React组件库(适配Next.js生态)
原生Flowbite基于Vanilla JS,在React中易出现 hydration 问题,官方提供的Flowbite React组件库完全适配React生态,无需手动处理JS:
- 安装依赖:
npm install flowbite-react
- 改写NavBar组件:
import { Dropdown } from 'flowbite-react'; const NavBar = () => { return ( <nav className="bg-white border-gray-200 px-2 sm:px-4 py-2.5 rounded dark:bg-gray-900"> <div className="container flex flex-wrap items-center justify-between mx-auto"> <a href="/" className="flex items-center"> <img src="https://flowbite.com/docs/images/logo.svg" className="h-6 mr-3 sm:h-9" alt="Flowbite Logo" /> <span className="self-center text-xl font-semibold whitespace-nowrap dark:text-white">Flowbite</span> </a> <div className="flex items-center md:order-2"> <Dropdown label={<img className="w-8 h-8 rounded-full" src="https://www.gravatar.com/avatar/357aeb5f4812fb9f69b0e21766c3b31b?s=48&d=identicon&r=PG&f=1" alt="user photo" />} placement="bottom" > <Dropdown.Header> <span className="block text-sm text-gray-900 dark:text-white">Bonnie Green</span> <span className="block text-sm font-medium text-gray-500 truncate dark:text-gray-400">name@flowbite.com</span> </Dropdown.Header> <Dropdown.Item>Dashboard</Dropdown.Item> <Dropdown.Item>Settings</Dropdown.Item> <Dropdown.Item>Earnings</Dropdown.Item> <Dropdown.Item>Sign out</Dropdown.Item> </Dropdown> <button data-collapse-toggle="mobile-menu-2" type="button" className="inline-flex items-center p-2 ml-1 text-sm text-gray-500 rounded-lg md:hidden hover:bg-gray-100 focus:outline-none focus:ring-2 focus:ring-gray-200 dark:text-gray-400 dark:hover:bg-gray-700 dark:focus:ring-gray-600" aria-controls="mobile-menu-2" aria-expanded="false"> <span className="sr-only">Open main menu</span> <svg className="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fillRule="evenodd" d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z" clipRule="evenodd"></path></svg> </button> </div> </div> </nav> ) } export default NavBar
这种方式遵循React组件逻辑,无JS初始化问题,是长期维护的最优解。
内容的提问来源于stack exchange,提问作者Crazy Coder
相关产品推荐
相关产品推荐

