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

Laravel Blade模板中FAQ展开/收起组件交互异常问题排查与解决

Laravel Blade模板中FAQ展开/收起组件交互异常问题排查与解决

嘿,我来帮你搞定这个FAQ组件的交互问题!从你的描述和代码来看,核心问题出在每个FAQ项都维护了自己独立的状态,而且初始状态设置不合理,导致后面的项默认展开,同时也没法实现“打开一个就关闭其他”的联动效果。

问题根源分析

  • 你最初的代码里,每个FAQ项都单独声明了<div x-data="{selected:0}">,这意味着每个项的selected状态是完全独立的,而且初始值设为0,直接触发了x-show="selected == 0"的显示条件,所以后面的FAQ答案默认就展开了。
  • 后来你尝试用$key绑定状态,但依然是每个项单独维护selected变量,还是没法实现“打开一个、自动关闭其他”的联动逻辑。

解决方案:状态提升+全局联动

我们需要把状态统一放到父容器中管理,让所有FAQ项共享同一个状态变量,这样就能轻松实现点击联动的效果。具体修改如下:

修正后的完整代码

<div class="wow fadeInUp" x-data="{ selected: null }">
    @foreach ($faqs as $key => $faq)
        <!-- FAQ项,建议添加wire:key避免Livewire更新时的DOM问题 -->
        <div class="flex flex-col border-b border-white/[0.15]" wire:key="faq-{{ $key }}">
            <h4 
                @click="selected === {{ $key }} ? selected = null : selected = {{ $key }}"
                class="cursor-pointer flex justify-between items-center font-semibold text-[22px] leading-[28px] py-5 lg:py-7"
                :class="selected === {{ $key }} ? 'text-white' : ''">
                {{ $faq->question }}

                <!-- 展开图标:未选中当前项时显示 -->
                <span :class="selected !== {{ $key }} ? 'block' : 'hidden'">
                    <svg class="fill-current" width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M22.5 11.1752H12.8625V1.5002C12.8625 1.0502 12.4875 0.637695 12 0.637695C11.55 0.637695 11.1375 1.0127 11.1375 1.5002V11.1752H1.50001C1.05001 11.1752 0.637512 11.5502 0.637512 12.0377C0.637512 12.4877 1.01251 12.9002 1.50001 12.9002H11.175V22.5002C11.175 22.9502 11.55 23.3627 12.0375 23.3627C12.4875 23.3627 12.9 22.9877 12.9 22.5002V12.8627H22.5C22.95 12.8627 23.3625 12.4877 23.3625 12.0002C23.3625 11.5502 22.95 11.1752 22.5 11.1752Z" fill="" />
                    </svg>
                </span>

                <!-- 收起图标:选中当前项时显示 -->
                <span :class="selected === {{ $key }} ? 'block' : 'hidden'">
                    <svg width="22" height="2" viewBox="0 0 22 2" fill="none" xmlns="http://www.w3.org/2000/svg">
                        <path d="M21.125 1.86263H0.875012C0.425012 1.86263 0.0125122 1.48763 0.0125122 1.00013C0.0125122 0.550134 0.387512 0.137634 0.875012 0.137634H21.125C21.575 0.137634 21.9875 0.512634 21.9875 1.00013C21.9875 1.45013 21.575 1.86263 21.125 1.86263Z" fill="white" />
                    </svg>
                </span>
            </h4>

            <!-- 答案区域:仅选中当前项时显示 -->
            <p x-show="selected === {{ $key }}" class="font-medium pb-7">
                {!! $faq->answer !!}
            </p>
        </div>
    @endforeach
</div>

关键改动说明

  1. 状态统一管理:把x-data="{ selected: null }"移到包裹所有FAQ的父容器,让所有项共享同一个状态变量,实现联动效果
  2. 初始状态修正:selected: null确保所有FAQ项默认处于收起状态
  3. 点击逻辑优化:点击时判断当前项的key是否等于全局selected值,相等则重置为null(收起),否则设置为当前key(展开)
  4. Livewire兼容:添加wire:key标识每个FAQ项,避免Livewire组件更新时DOM重新渲染导致的状态异常

这样修改后,就能完全实现你想要的效果:默认所有FAQ收起,点击任意项展开对应答案,同时自动关闭其他已展开的答案。

备注:内容来源于stack exchange,提问作者tesseract

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:43:01