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

Laravel Livewire导航后JavaScript功能失效,仅全页刷新可用的问题求助

Laravel Livewire导航后JavaScript功能失效,仅全页刷新可用的问题求助

我在自己的应用里用Laravel Livewire做导航,默认布局里包含以下结构和脚本:

<div class="flex grow">
        <x-layouts.sidebar />
        <!-- End of Sidebar -->
        <!-- Wrapper -->
        <div class="wrapper flex grow flex-col">
            <!-- Header -->
            <x-layouts.header />
            <main class="grow content pt-5" id="content" role="content">
                {{ $slot }}
            </main>
            <x-layouts.footer />
            <!-- End of Footer -->
        </div>
        <!-- End of Wrapper -->
</div>

<script src="v2/assets/js/core.bundle.js"></script>
<script src="v2/assets/vendors/apexcharts/apexcharts.min.js"></script>
<script src="v2/assets/js/widgets/general.js"></script>
<script src="v2/assets/js/layouts/demo1.js"></script>

当我全页刷新的时候,一切都正常——侧边栏切换、下拉菜单这些JavaScript功能都能正常工作。但用Livewire.navigate在组件间导航的时候,JavaScript就失效了。哪怕用Livewire导航回同一个页面,功能也恢复不了,只有全页刷新才能解决。

我尝试过的方法

Livewire事件监听器

我试着用livewire:navigated、livewire:navigating和livewire:navigate事件来重新初始化脚本,代码如下:

<script>
    document.addEventListener('livewire:navigated', () => {
        console.log('true working');
        @php
            $scripts = [
                public_path('v2/assets/js/core.bundle.js'),
                public_path('v2/assets/vendors/apexcharts/apexcharts.min.js'),
                public_path('v2/assets/js/widgets/general.js'),
                public_path('v2/assets/js/layouts/demo1.js'),
            ];

            foreach ($scripts as $script) {
                if (file_exists($script)) {
                    echo file_get_contents($script);
                } else {
                    echo "// File not found: " . basename($script) . "\n";
                }
            }
        @endphp
    });
</script>

事件监听器确实触发了,脚本也加载到DOM里了(通过Network标签验证过),但导航之后功能还是不能用。

手动添加脚本

我把一个自定义脚本文件放在webpackUniversalModuleDefinition函数外面,手动引入后,哪怕用Livewire导航也能正常工作。这让我怀疑问题可能和Webpack打包脚本的方式或者语法有关。

我的猜测和观察

Webpack通用模块定义

我的脚本都是用下面这种模式打包的:

(function webpackUniversalModuleDefinition(root, factory) {
    if (typeof exports === 'object' && typeof module === 'object')
        module.exports = factory();
    else if (typeof define === 'function' && define.amd)
        define([], factory);
    else {
        var a = factory();
        for (var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
    }
})(self, function() {
    // Module code here
});

我怀疑这种打包方式就是导航后功能失效的原因,但搞不懂为什么全页刷新的时候又能正常工作。

全局作用域问题

也许打包后的脚本没有把功能暴露到全局作用域(比如window或者self),所以在Livewire的部分DOM更新之后就访问不到了。

导航时的脚本执行

我注意到,如果把逻辑放在Webpack的包裹外面(比如直接放在<script>标签里,或者脚本文件的最底部),导航后就能正常工作。这让我觉得问题出在函数的注册或者初始化方式上。

我想弄明白的问题

  • 为什么Webpack打包的脚本在全页刷新时能用,但Livewire导航后就不行?
  • 这个问题和Webpack暴露函数或者注册到全局作用域的方式有关吗?
  • 有没有什么好办法能让这类脚本在Livewire导航后也能无缝工作?
  • 这个问题会不会和缓存、模块初始化或者Livewire的部分DOM更新有关?

我希望侧边栏切换、下拉菜单这些JavaScript功能,在用Livewire.navigate导航到新组件后,能和全页刷新时一样正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.15 10:54:28