Laravel 9+Breeze组件在<td>内失效:AlpineJS指令丢失
问题解决:Laravel Blade模态框组件在内@click.outside失效
问题说明
在Laravel 9 + Laravel Breeze项目中,自定义的删除确认模态框组件在标签外调用时功能完全正常,但放入内后,@click.outside="open = false"和@close.stop="open = false"指令失效,无法通过点击外部或触发close事件关闭模态框。
解决方案
方案1:用Alpine x-teleport将模态框挂载到body(推荐)
表格DOM结构的事件冒泡规则或定位限制会干扰Alpine的事件监听,将模态框脱离表格层级挂载到body下即可解决:
@props(['route', 'idSupprimer' => null]) <div x-data="{ open: false }" @click.outside="open = false" @close.stop="open = false"> <x-button @click="open = ! open" :palette="'danger'" type="button">{{ $trigger }}</x-button> <!-- 用x-teleport把模态框移到body下,脱离表格DOM --> <x-teleport to="body"> <div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="transform opacity-0" x-transition:enter-end="transform opacity-100" x-transition:leave="transition ease-in duration-75" x-transition:leave-start="transform opacity-100" x-transition:leave-end="transform opacity-0" style="display: none; background-color: hsla(0,0%,0%,0.5)" class="fixed inset-0 flex justify-center items-center z-50"> <div class="rounded-md ring-1 ring-black ring-opacity-5 bg-white p-6"> <div>{{$message}}</div> <div class="flex justify-center"> <x-button @click="open = false" class="mx-1 bg-gray-400" :palette="'principale'" type="button">Annuler</x-button> @if($idSupprimer) <x-link-button href="{{ route($route, $idSupprimer) }}" class="mx-1 bg-red-600" :palette="'principale'">{{ $trigger }}</x-link-button> @else <x-link-button href="{{ route($route) }}" class="mx-1 bg-red-600" :palette="'principale'">{{ $trigger }}</x-link-button> @endif </div> </div> </div> </x-teleport> </div>
- 核心改动:通过
<x-teleport to="body">将模态框容器移到body下,避免表格元素的事件干扰 - 定位优化:把
absolute top-0 left-0 h-screen w-screen改为fixed inset-0,确保遮罩层全屏覆盖,不受父元素定位影响
方案2:替换@简写为完整x-on语法
部分场景下,表格元素内Blade对@符号的解析可能存在冲突,尝试用完整语法替代简写:
@props(['route', 'idSupprimer' => null]) <div x-data="{ open: false }" x-on:click.outside="open = false" x-on:close.stop="open = false"> <x-button x-on:click="open = ! open" :palette="'danger'" type="button">{{ $trigger }}</x-button> <div x-show="open" x-transition:enter="transition ease-out duration-200" x-transition:enter-start="transform opacity-0" x-transition:enter-end="transform opacity-100" x-transition:leave="transition ease-in duration-75" x-transition:leave-start="transform opacity-100" x-transition:leave-end="transform opacity-0" style="display: none; background-color: hsla(0,0%,0%,0.5)" class="fixed inset-0 flex justify-center items-center z-50"> <div class="rounded-md ring-1 ring-black ring-opacity-5 bg-white p-6"> <div>{{$message}}</div> <div class="flex justify-center"> <x-button x-on:click="open = false" class="mx-1 bg-gray-400" :palette="'principale'" type="button">Annuler</x-button> @if($idSupprimer) <x-link-button href="{{ route($route, $idSupprimer) }}" class="mx-1 bg-red-600" :palette="'principale'">{{ $trigger }}</x-link-button> @else <x-link-button href="{{ route($route) }}" class="mx-1 bg-red-600" :palette="'principale'">{{ $trigger }}</x-link-button> @endif </div> </div> </div> </div>
内容的提问来源于stack exchange,提问作者ArchonSlime
相关产品推荐
相关产品推荐

