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

Livewire3中点击wire:navigate后JS失效及标识符重复问题

Livewire 3 wire:navigate 导致自定义JS失效及变量重复声明问题解决

问题场景

在Livewire 3的全页组件app布局中,添加了侧边栏开合的JavaScript代码,初始运行正常。但点击带有wire:navigate属性的链接后,页面自定义JS失效,且控制台报错:Identifier 'adminHamburger' has already been declared at swapCurrentPageWithNewHtml。

相关代码如下:

自定义侧边栏JS代码

const adminHamburger = document.querySelector('#admin-hamburger');
const sidebar = document.querySelector('aside');

adminHamburger.addEventListener('click', function() {
  sidebar.classList.toggle('translate-x-64');
});

布局代码

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}" dir="rtl">

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="csrf-token" content="{{ csrf_token() }}">

  <title>{{ config('app.name', 'Laravel') }}</title>

  <!-- Fonts -->
  <link rel="preconnect" href="https://fonts.bunny.net">
  <link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />

  <!-- Scripts -->
  @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>

<body class="font-sans antialiased">
  <div class="min-h-screen">
    @include('layouts.back.header')
    @include('layouts.back.sidebar')

    <!-- Page Content -->
    <main>
      {{ $slot }}
    </main>

    @include('layouts.back.footer')

    <script>
      const adminHamburger = document.querySelector('#admin-hamburger');
      const sidebar = document.querySelector('aside');

      adminHamburger.addEventListener('click', function() {
        sidebar.classList.toggle('translate-x-64');
      });
    </script>
  </div>
</body>

</html>

路由配置

Route::get('/admin', App\Livewire\Back\Index::class);

问题原因

Livewire的wire:navigate采用AJAX局部替换页面内容的方式实现无刷新跳转,不会重新加载整个页面:

  1. 原布局中的<script>会在每次页面替换后再次执行,const声明的全局变量会因重复定义抛出错误;
  2. 旧页面中的DOM元素被替换后,原绑定的事件监听失效,新元素未重新绑定监听,导致JS功能失效。

解决方案

方案1:使用事件委托(推荐)

将事件监听绑定到全局document上,通过判断点击目标实现功能,避免元素替换后监听失效,同时避免全局变量重复声明问题:

替换布局中的<script>代码为:

document.addEventListener('click', function(e) {
  if (e.target.id === 'admin-hamburger') {
    const sidebar = document.querySelector('aside');
    sidebar.classList.toggle('translate-x-64');
  }
});

方案2:利用Livewire livewire:navigated事件

在每次wire:navigate跳转完成后,重新获取元素并绑定监听,同时处理变量重复声明问题:

替换布局中的<script>代码为:

document.addEventListener('livewire:navigated', function() {
  // 使用let避免重复声明错误
  let adminHamburger = document.querySelector('#admin-hamburger');
  const sidebar = document.querySelector('aside');

  // 克隆元素清除旧监听,避免重复绑定
  adminHamburger.replaceWith(adminHamburger.cloneNode(true));
  adminHamburger = document.querySelector('#admin-hamburger');

  adminHamburger.addEventListener('click', function() {
    sidebar.classList.toggle('translate-x-64');
  });
});

方案3:将代码移至app.js并使用Livewire钩子

将JS代码放到resources/js/app.js中,利用Livewire的初始化钩子:

document.addEventListener('livewire:initialized', function() {
  // 绑定navigated事件
  document.addEventListener('livewire:navigated', function() {
    const adminHamburger = document.querySelector('#admin-hamburger');
    const sidebar = document.querySelector('aside');

    adminHamburger.addEventListener('click', function() {
      sidebar.classList.toggle('translate-x-64');
    });
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 13:01:26