React结合Tailwindcss实现移动端导航栏显隐过渡效果
实现方案
你当前技术栈已经包含Headless UI,直接使用其内置的Transition组件实现过渡动画是成本最低、适配性最好的方案,不需要额外引入第三方动画库。该组件会自动在元素离场时等待动画执行完成再卸载DOM节点,完美解决你当前直接条件渲染无动画的问题。
实现步骤
1. 修改Navbar组件
首先从Headless UI引入Transition组件,将原有的条件渲染逻辑替换为Transition包裹结构,配置Tailwind过渡类实现「下滑+淡入」的常规移动端导航动画效果:
import { useState } from 'react'; import { Transition } from '@headlessui/react'; import { FiMenu } from 'react-icons/fi'; import MobileMenu from './MobileMenu'; function Navbar() { const [mobileMenuOpen, setMobileMenuOpen] = useState(false); return ( <> <nav className="flex justify-between items-center px-4 lg:px-8 py-3 bg-gray-900 text-white"> {/* Mobile Menu Icon */} <div className="block md:hidden p-2 cursor-pointer rounded-full hover:bg-gray-700 transition duration-200" onClick={() => setMobileMenuOpen(!mobileMenuOpen)} > <FiMenu size={20} /> </div> </nav> {/* 带动画的移动端菜单 */} <Transition show={mobileMenuOpen} unmount={true} enter="transition duration-200 ease-out" enterFrom="opacity-0 -translate-y-2" enterTo="opacity-100 translate-y-0" leave="transition duration-150 ease-in" leaveFrom="opacity-100 translate-y-0" leaveTo="opacity-0 -translate-y-2" > <MobileMenu /> </Transition> </> ); } export default Navbar;
注:原代码中
transition-2为无效类名,已替换为标准Tailwind类transition duration-200实现按钮hover的平滑过渡。
2. (可选)增加菜单项错落动画
如果想要菜单内的导航项依次出现的错落效果,可以在MobileMenu中使用Transition.Child组件,给每个子项设置不同的延迟时间即可,修改后的MobileMenu代码如下:
import { Transition } from '@headlessui/react'; import { ImHome } from 'react-icons/im'; import { HiUsers } from 'react-icons/hi'; import { CgProfile } from 'react-icons/cg'; function MobileMenu() { return ( <div className="block md:hidden px-4 py-3 text-white w-full bg-gray-800 border-t border-opacity-70 border-slate-700"> <Transition.Child enter="transition duration-200 ease-out delay-100" enterFrom="opacity-0 translate-x-[-10px]" enterTo="opacity-100 translate-x-0" leave="transition duration-100 ease-in" leaveFrom="opacity-100 translate-x-0" leaveTo="opacity-0 translate-x-[-10px]" > <div className="flex items-center mb-3 pb-3 border-b border-slate-700"> <img src="https://africaprime.com/wp-content/uploads/2020/04/ElonMusk.jpg" className="rounded-full w-8 h-8 cursor-pointer" /> <h6 className="ml-5 cursor-pointer">Elon Musk</h6> </div> </Transition.Child> <Transition.Child enter="transition duration-200 ease-out delay-150" enterFrom="opacity-0 translate-x-[-10px]" enterTo="opacity-100 translate-x-0" leave="transition duration-100 ease-in delay-50" leaveFrom="opacity-100 translate-x-0" leaveTo="opacity-0 translate-x-[-10px]" > <div className="mobile-nav-icon flex items-center py-2"> <ImHome size={20} /> <h4 className="ml-5">Home</h4> </div> </Transition.Child> <Transition.Child enter="transition duration-200 ease-out delay-200" enterFrom="opacity-0 translate-x-[-10px]" enterTo="opacity-100 translate-x-0" leave="transition duration-100 ease-in" leaveFrom="opacity-100 translate-x-0" leaveTo="opacity-0 translate-x-[-10px]" > <div className="mobile-nav-icon flex items-center py-2"> <HiUsers size={20} /> <h4 className="ml-5">Friends</h4> </div> </Transition.Child> <Transition.Child enter="transition duration-200 ease-out delay-250" enterFrom="opacity-0 translate-x-[-10px]" enterTo="opacity-100 translate-x-0" leave="transition duration-100 ease-in" leaveFrom="opacity-100 translate-x-0" leaveTo="opacity-0 translate-x-[-10px]" > <div className="mobile-nav-icon flex items-center py-2"> <CgProfile size={20} /> <h4 className="ml-5">My Profile</h4> </div> </Transition.Child> </div> ); } export default MobileMenu;
小提示:原代码中
mobile-nav-icon类缺少flex布局,图标和文字无法对齐,已补充flex items-center py-2优化点击区域和排版。
动画参数调整说明
你可以根据自己的设计需求修改对应类名调整动画效果:
- 调整
duration-200/duration-150的数值可以修改动画快慢 - 把
-translate-y-2换成-translate-y-full可以实现整屏从上滑入的效果 - 修改
delay-*的数值可以调整菜单项错落动画的间隔时间 - 替换ease函数(比如
ease-in-out)可以修改动画的加速度曲线
内容的提问来源于stack exchange,提问作者M7md-Dev
相关产品推荐
相关产品推荐

