Laravel Livewire升级后加载异常:window.Livewire.find未定义
解决Livewire 3 + Jetstream 4 模态框触发时
window.Livewire.find(...) is undefined错误 问题情况
点击个人资料页的「删除账户」按钮触发模态框时,控制台报错:Uncaught TypeError: window.Livewire.find(...) is undefined,但页面完全加载完成后,手动在控制台执行window.Livewire.find(...)却能正常返回结果。
版本升级记录
Composer 依赖
"laravel/jetstream": "^3.2" → "^4.0", "livewire/livewire": "^2.11" → "^v3.0",
NPM 依赖
"alpinejs": "^3.0.6" → "^3.13.2",
相关代码
delete-user-form.blade.php
<div class="mt-5"> <x-danger-button wire:click="confirmUserDeletion" wire:loading.attr="disabled"> {{ __('Delete Account') }} </x-danger-button> </div> <!-- Delete User Confirmation Modal --> <x-dialog-modal wire:model.live="confirmingUserDeletion"> ... 模态框内容 ... </x-dialog-modal>
app.blade.php
<head> <!-- Scripts --> @vite(['resources/scss/app.scss', 'resources/js/app.js', 'node_modules/trix/dist/trix.esm.min.js', 'node_modules/trix/dist/trix.css']) <!-- Styles --> @livewireStyles </head> <body class="font-sans antialiased"> ... 页面内容 ... @stack('modals') @livewireScripts </body>
解决步骤
1. 确保Alpine.js优先于Livewire初始化
Livewire 3对Alpine的加载顺序有严格要求,必须让Alpine先完成初始化。修改resources/js/app.js:
import Alpine from 'alpinejs'; window.Alpine = Alpine; Alpine.start(); // 若通过npm安装Livewire,在此之后导入 import Livewire from 'livewire';
如果用CDN加载脚本,把Alpine的CDN链接放在Livewire CDN之前。
2. 清理缓存并同步Jetstream组件
Jetstream 4适配了Livewire 3,但旧缓存可能导致兼容性问题,执行以下命令清理:
php artisan view:clear php artisan cache:clear php artisan livewire:clear
同时确认模态框的wire:model.live语法符合Livewire 3规范(Livewire 3中.live是默认绑定模式,显式声明没问题)。
3. 调整Vite加载配置
检查vite.config.js,确保脚本入口正确,避免Vite打乱加载顺序:
// vite.config.js export default defineConfig({ plugins: [ laravel({ input: ['resources/js/app.js', 'resources/scss/app.scss'], refresh: true, }), ], });
4. 临时替换模态框组件(若上述方案无效)
如果Jetstream的x-dialog-modal组件仍有兼容性问题,可以临时改用原生Livewire写法的模态框:
<div x-show="confirmingUserDeletion" class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"> <div class="bg-white rounded-lg p-6 w-full max-w-md"> <h3 class="text-lg font-medium text-gray-900">{{ __('确认删除账户?') }}</h3> <div class="mt-4 text-sm text-gray-600"> {{ __('账户删除后所有资源和数据会被永久清除,请输入密码确认操作。') }} </div> <div class="mt-6"> <x-input type="password" wire:model="password" placeholder="{{ __('密码') }}" class="w-full" /> </div> <div class="mt-6 flex justify-end gap-2"> <x-secondary-button wire:click="cancelUserDeletion"> {{ __('取消') }} </x-secondary-button> <x-danger-button wire:click="deleteUser" wire:loading.attr="disabled"> {{ __('删除账户') }} </x-danger-button> </div> </div> </div>
内容的提问来源于stack exchange,提问作者Bloxxor
相关产品推荐
相关产品推荐

