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

Livewire3:组件切换时JS重复加载问题的排查与解决

问题描述

使用Livewire 3开发后台管理系统时,通过侧边栏(<livewire:sidebar />)中带wire:navigate属性的链接切换Livewire组件,网络面板显示所有JS文件(如app.js)都会重复加载,但这些JS仅需在首次加载时运行一次。以下是相关代码结构:

admin\layouts\master.blade.php

<!DOCTYPE html>
<html lang="en">
@include('admin.layouts.header-scripts')
<body class="hold-transition sidebar-mini">
<div class="wrapper">
    
    @include('admin.layouts.nav')
    
    <livewire:sidebar />
    
    {{ $slot }}
    
</div>
@include('admin.layouts.footer-scripts')
</body>
</html>

admin\layouts\header-scripts.blade.php

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="x-ua-compatible" content="ie-edge">

    <title> {{ $title ?? 'Home' }} | Admin Panel </title>
    <link rel="icon" type="image/x-icon" href="https://www.w3schools.com/favicon.ico">
    <!-- Font Awesome Icons -->
    <link rel="stylesheet" href="{{asset('bower_components/admin-lte/plugins/fontawesome-free/css/all.min.css')}}">
    <!-- Theme style -->
    <link rel="stylesheet" href="{{asset('bower_components/admin-lte/dist/css/adminlte.min.css')}}">
    <link rel="stylesheet" href="{{asset('bower_components/admin-lte/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css')}}">
    <link rel="stylesheet" href="{{asset('bower_components/admin-lte/plugins/datatables-responsive/css/responsive.bootstrap4.min.css')}}">
    <link rel="stylesheet" href="{{asset('bower_components/admin-lte/dist/css/adminlte.min.css')}}">
    <link rel="stylesheet" href="{{asset('bower_components/admin-lte/plugins/summernote/summernote-bs4.css')}}">

    <!-- Google Font: Source Sans Pro -->
    <link href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700" rel="stylesheet">
    @yield('styles')
    @livewireStyles
</head>
<script src="{{asset('js/app.js')}}"></script>
<!-- Bootstrap 4 -->
<script src="{{ asset('bower_components/admin-lte/plugins/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<!-- AdminLTE App -->
<script src="{{ asset('bower_components/admin-lte/dist/js/adminlte.min.js') }}"></script>

@yield('js')
@livewireScripts

views\livewire\sidebar.blade.php

<aside class="main-sidebar sidebar-dark-primary elevation-4">
    
    <div class="sidebar">
        
        <nav class="mt-2">
            <ul class="nav nav-pills nav-sidebar flex-column" data-widget="treeview" role="menu"
                data-accordion="false">
                
                <li class="nav-item">
                    <a href="/home" wire:navigate
                       class="nav-link {{ request()->is('home') ? 'active' : '' }}">
                        <i class="nav-icon fas fa-home"></i>
                        Dashboard
                    </a>
                </li>
                <li class="nav-item">
                    <a href="/getAbout" wire:navigate
                       class="nav-link {{ request()->is('getAbout*') ? 'active' : '' }}">
                        <i class="nav-icon fas fa-cog"></i>
                        About Us
                    </a>
                </li>
            </ul>
        </nav>
        
    </div>
</aside>

web.php

Route::get('/home', HomeIndex::class);

Route::get('/getAbout', AboutIndex::class);

app\Http\Livewire\HomeIndex.php

<?php

namespace App\Http\Livewire;

use Livewire\Attributes\Title;
use Livewire\Component;

class HomeIndex extends Component
{
    #[Title('Home')]

    public $title = 'Dashboards';

    public function render()
    {
        return view('livewire.home-index');
    }
}

views\livewire\home-index.blade.php

<div class="content-wrapper">
   Home Index page
</div>

getAbout对应的Livewire内容与上述类似。


解决方案

<head>中的脚本仅会加载一次,但<body>中的脚本会在每次页面切换时重新执行——这是因为Livewire使用wire:navigate切换页面时,会替换<body>的全部内容,新页面中的所有<script>标签都会被执行:

<!-- 页面一 -->
<body>
    <script>
        console.log('在页面一执行')
    </script>
</body>
 
<!-- 页面二 -->
<body>
    <script>
        console.log('在页面二执行')
    </script>
</body>

如果希望<body>中的某个<script>标签仅在首次页面访问时运行,只需为其添加data-navigate-once属性,Livewire就只会在初始加载时执行它:

<script data-navigate-once src="{{asset('js/app.js')}}"></script>
<script data-navigate-once src="{{ asset('bower_components/admin-lte/plugins/bootstrap/js/bootstrap.bundle.min.js') }}"></script>
<script data-navigate-once src="{{ asset('bower_components/admin-lte/dist/js/adminlte.min.js') }}"></script>

修改你的footer-scripts.blade.php文件,给所有需要仅加载一次的脚本标签加上data-navigate-once属性,即可解决重复加载问题。

内容的提问来源于Stack Exchange,提问作者Shiva Kunwar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:47:03