添加wire:navigate后daterangepicker.js无法加载的问题求助
我在Web应用中使用daterangepicker组件,当给导航链接添加wire:navigate后,控制台出现错误,daterangepicker无法正常加载:
错误信息
Uncaught TypeError: $(...).daterangepicker is not a function at <anonymous>:2:49 at swapCurrentPageWithNewHtml (livewire.js?id=951e6947:7730:19) at livewire.js?id=951e6947:7910:11 at preventAlpineFromPickingUpDomChanges (livewire.js?id=951e6947:7987:5) at livewire.js?id=951e6947:7900:9 at prefetches.<computed>.whenFinished (livewire.js?id=951e6947:7462:9) at storeThePrefetchedHtmlForWhenALinkIsClicked (livewire.js?id=951e6947:7446:11) at livewire.js?id=951e6947:7878:11 at livewire.js?id=951e6947:7438:7 at livewire.js?id=951e6947:7425:7
初始化代码
<script> $('input[name="dtmDispatchDateRange"]').daterangepicker({ locale:{ format: 'MM/DD/YYYY' } }); var date1 = document.getElementById("date1") var date2 = document.getElementById("date2") var contentToChange = document.getElementById("dates") contentToChange.value = date1.textContent + " - " + date2.textContent </script>
效果对比
- 未添加
wire:navigate:daterangepicker正常显示 - 添加
wire:navigate后:组件无法渲染,仅显示普通输入框
布局头部资源引入
<script type="text/javascript" src="{{ asset('assets-bs5/datapicker/moment.min.js') }}"></script> <script type="text/javascript" src="{{ asset('assets-bs5/datapicker/daterangepicker.min.js') }}"></script> <link rel="stylesheet" type="text/css" href="{{ asset('assets-bs5/datapicker/daterangepicker.css') }}" />
补充表单代码(2025年1月3日编辑)
@extends('layouts.app') @section('content') @php $title = 'Manifest' @endphp @include('layouts.components.page_title_content_section') @include('layouts.components.page_error_section') <div style="display: none"> <div id="date1">{{ isset($dtmDispatchDate1) ? (\Carbon\Carbon::parse($dtmDispatchDate1)->format('m/d/Y')) : '' }}</div> <div id="date2">{{ isset($dtmDispatchDate2) ? (\Carbon\Carbon::parse($dtmDispatchDate2)->format('m/d/Y')) : '' }}</div> </div> <section data-bs-version="5.3"> <div class="container-fluid"> <div class="row justify-content-center"> <div class=""> <blockquote style="border-color: #39b451; background-color: #EBECEE; height: 170px;"> <div id="externalGrids" class=""> <label for="intOrderId">Order No:</label><br> <span id="intOrderId"></span> </div> <div id="externalGrids" class=""> <label for="strLoadId">Load Id:</label><br> <span id="strLoadId"></span> </div> <div id="externalGrids" class=""> <label for="strDeliveryMethod">Delivery Method:</label><br> <span style="width: 50px" id="strDeliveryMethod"></span> </div> <div id="externalGrids" class=""> <label for="strDispatchDate">Dispatch Date:</label><br> <span style="width: 50px" id="strDispatchDate"></span> </div> <form method="get" action=""> <div id="externalGrids" class="" > <label for="">Dispatch Date</label><br> <input style="width: 200px" id="dates" name="dtmDispatchDateRange" type="text" autocomplete="off" > </div> <div id="externalGrids" class=""> <label for="">Show</label><br> <button style="background-color: #36b551; color: whitesmoke; width: 90px;">OK</button> </div> </form> </blockquote> </div> </div> </div> </section> <section > <div class="container-fluid" style=""> <table class="table table-bordered" > <thead> <tr id="table_header"> <th class="text-nowrap">Order No</th> <th class="text-nowrap">Load ID</th> <th class="text-nowrap">Delivery Method</th> <th class="text-nowrap">Dispatch Date</th> <th class="text-center">Order Qty</th> <th class="text-center">Status</th> <th class="text-center">Status</th> </tr> </thead> <tbody> @foreach($orders as $item) <tr id=""> <td>..........</td> </tr> @endforeach </tbody> </table> </div> </section> <script> $('input[name="dtmDispatchDateRange"]').daterangepicker({ locale:{ format: 'MM/DD/YYYY' } }); var date1 = document.getElementById("date1") var date2 = document.getElementById("date2") var contentToChange = document.getElementById("dates") contentToChange.value = date1.textContent + " - " + date2.textContent </script> @stop
解决方法
核心原因
wire:navigate是无刷新导航,页面切换时仅更新部分DOM,不会重新加载头部脚本;原初始化代码仅在首次页面加载时执行,新DOM渲染后无法重新初始化组件,甚至可能因为jQuery/daterangepicker实例丢失,导致找不到daterangepicker方法。
方案1:监听Livewire导航事件重新初始化
封装初始化逻辑,监听Livewire的navigated事件,每次导航完成后重新初始化组件:
<script> function initDateRangePicker() { // 先销毁已存在的实例,避免重复绑定 $('input[name="dtmDispatchDateRange"]').daterangepicker('destroy').daterangepicker({ locale:{ format: 'MM/DD/YYYY' } }); // 设置初始日期值 const date1 = document.getElementById("date1") const date2 = document.getElementById("date2") const contentToChange = document.getElementById("dates") if (date1 && date2 && contentToChange) { contentToChange.value = date1.textContent + " - " + date2.textContent } } // 首次加载执行 document.addEventListener('DOMContentLoaded', initDateRangePicker); // 无刷新导航完成后重新执行 document.addEventListener('livewire:navigated', initDateRangePicker); </script>
方案2:标记脚本为持久化
如果jQuery/daterangepicker实例在导航后丢失,可在布局头部的脚本标签添加wire:persist,让Livewire保留这些脚本实例:
<script type="text/javascript" src="{{ asset('assets-bs5/datapicker/moment.min.js') }}" wire:persist></script> <script type="text/javascript" src="{{ asset('assets-bs5/datapicker/daterangepicker.min.js') }}" wire:persist></script> <link rel="stylesheet" type="text/css" href="{{ asset('assets-bs5/datapicker/daterangepicker.css') }}" />
方案3:用Alpine.js生命周期钩子(推荐)
如果项目搭配了Alpine.js,直接用其组件生命周期钩子,每次DOM挂载时自动初始化:
<input style="width: 200px" id="dates" name="dtmDispatchDateRange" type="text" autocomplete="off" x-data="{ init() { $(this.$el).daterangepicker({ locale:{ format: 'MM/DD/YYYY' } }); // 设置初始值 const date1 = document.getElementById('date1'); const date2 = document.getElementById('date2'); if (date1 && date2) { this.$el.value = date1.textContent + ' - ' + date2.textContent; } } }" >
内容的提问来源于stack exchange,提问作者fumfel20
相关产品推荐
相关产品推荐

