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

如何在NextJS+Tailwind CSS中实现酒店设施展开收起功能

问题

我正在开发一个展示酒店设施的页面,希望实现一个可隐藏的设施区块:点击「Show more amenities」按钮可展开该区块,点击「Show less amenities」按钮可将其收起。请问如何在NextJS框架中配合Tailwind CSS完成此交互功能?

示例1(收起状态):
收起状态的设施区块

示例2(展开状态的设施区块):
展开状态的设施区块

现有代码片段:

'use client'

import Image from 'next/image'

import { useState, useEffect } from "react";

export default function Lodge() {

    return (
        <div className="w-full h-[8964px] bg-white shadow-sm">

            <div className="grid grid-cols-2 gap-4">

                ...

                        <div className="text-[28px] font-medium leading-normal text-[#313131] underline flex flex-row gap-5 py-16 cursor-pointer">
                            Show more amenties
                            <Image
                                src="/images/icon down.svg"
                                alt="icon-down"
                                width={26}
                                height={26}
                            />
                        </div>

                        <div className="grid grid-cols-2 gap-4">

                            <div className="">
                                <div className="text-[32px] font-bold leading-normal text-[#313131]">
                                    Heating & Cooling
                                    <div className="text-[24px] font-medium leading-normal text-[#313131] flex flex-row items-end gap-5">
                                        <Image
                                            src="/images/lodge/fan icon.svg"
                                            alt="fan-icon"
                                            width={40}
                                            height={40}
                                        />
                                        Portable fans
                                    </div>
                                </div>

                                <div className="text-[32px] font-bold leading-normal text-[#313131]">
                                    Internet & Working
                                    <div className="text-[24px] font-medium leading-normal text-[#313131] flex flex-row items-end gap-5">
                                        <Image
                                            src="/images/lodge/wifi icon.svg"
                                            alt="wifi-icon"
                                            width={40}
                                            height={40}
                                        />
                                        WI-FI
                                    </div>
                                    <div className="text-[24px] font-medium leading-normal text-[#313131] flex flex-row items-end gap-5">
                                        <Image
                                            src="/images/lodge/desk icon.svg"
                                            alt="desk-icon"
                                            width={40}
                                            height={40}
                                        />
                                        Working zone
                                    </div>
                                </div>
                             ... etc
解决方案

1. 用useState管理展开状态

在组件内部添加状态变量控制设施区块的显示/隐藏,初始设为false(默认收起)。

2. 修改按钮交互逻辑

  • 根据状态切换按钮文本:展开时显示「Show less amenities」,收起时显示「Show more amenities」
  • 给按钮绑定点击事件,切换状态值
  • 图标可通过Tailwind的旋转类实现方向切换,无需额外图标资源

3. 用Tailwind控制区块显示与动画

给设施区块添加条件类,实现平滑的展开/收起过渡:

  • 收起状态:max-h-0 overflow-hidden opacity-0
  • 展开状态:max-h-[2000px] opacity-100
  • 配合transition-all duration-300实现动画效果

完整修改代码

'use client'

import Image from 'next/image'
import { useState } from "react";

export default function Lodge() {
    // 管理设施区块展开状态,默认收起
    const [isAmenitiesExpanded, setIsAmenitiesExpanded] = useState(false);

    // 切换展开/收起状态
    const toggleAmenities = () => {
        setIsAmenitiesExpanded(!isAmenitiesExpanded);
    };

    return (
        <div className="w-full h-[8964px] bg-white shadow-sm">
            <div className="grid grid-cols-2 gap-4">
                {/* 其他页面内容 */}
                ...

                {/* 切换按钮 */}
                <div 
                    onClick={toggleAmenities}
                    className="text-[28px] font-medium leading-normal text-[#313131] underline flex flex-row items-center gap-5 py-16 cursor-pointer"
                >
                    {isAmenitiesExpanded ? 'Show less amenities' : 'Show more amenities'}
                    <Image
                        src="/images/icon down.svg"
                        alt={isAmenitiesExpanded ? "icon-up" : "icon-down"}
                        width={26}
                        height={26}
                        className={`transition-transform ${isAmenitiesExpanded ? 'rotate-180' : ''}`}
                    />
                </div>

                {/* 设施区块:带过渡动画的显示/隐藏 */}
                <div className={`grid grid-cols-2 gap-4 transition-all duration-300 ease-in-out ${isAmenitiesExpanded ? 'opacity-100 max-h-[2000px]' : 'opacity-0 max-h-0 overflow-hidden'}`}>
                    <div className="">
                        <div className="text-[32px] font-bold leading-normal text-[#313131]">
                            Heating & Cooling
                            <div className="text-[24px] font-medium leading-normal text-[#313131] flex flex-row items-end gap-5">
                                <Image
                                    src="/images/lodge/fan icon.svg"
                                    alt="fan-icon"
                                    width={40}
                                    height={40}
                                />
                                Portable fans
                            </div>
                        </div>

                        <div className="text-[32px] font-bold leading-normal text-[#313131]">
                            Internet & Working
                            <div className="text-[24px] font-medium leading-normal text-[#313131] flex flex-row items-end gap-5">
                                <Image
                                    src="/images/lodge/wifi icon.svg"
                                    alt="wifi-icon"
                                    width={40}
                                    height={40}
                                />
                                WI-FI
                            </div>
                            <div className="text-[24px] font-medium leading-normal text-[#313131] flex flex-row items-end gap-5">
                                <Image
                                    src="/images/lodge/desk icon.svg"
                                    alt="desk-icon"
                                    width={40}
                                    height={40}
                                />
                                Working zone
                            </div>
                        </div>
                        {/* 其他设施内容 */}
                        ... etc
                    </div>
                </div>
            </div>
        </div>
    );
}

关键说明

  • 依托Next.js客户端组件的useState实现状态管理,符合框架规范
  • 使用max-h而非hidden实现动画,避免元素直接消失的生硬感
  • 图标旋转通过rotate-180类实现,减少资源文件依赖

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 05:52:33