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

Livewire组件刷新后Leaflet.js地图消失问题求助

解决Livewire组件刷新后Leaflet地图消失的问题

问题核心是Livewire刷新时会重新渲染DOM,原有的Leaflet地图实例与DOM元素的绑定失效,导致地图消失。以下是修复方案:

修复步骤

  • 将地图初始化逻辑封装为可复用函数,支持传入初始坐标
  • 监听Livewire的refresh事件,组件刷新后重新初始化地图
  • 保留用户已选择的坐标,刷新后自动恢复标记位置

修改后的完整代码

<div>
    <x-slot name="header">
        {{ __('Create Campaign') }}
    </x-slot>

    <div class="p-4 rounded-lg shadow-xs flex items-center justify-center">
        <div class="w-8/12">
            <x-mary-form wire:submit="save">
                <x-mary-input label="Name" wire:model="name" icon="o-user"/>
                <x-mary-textarea label="Description" wire:model="description"/>
                <x-mary-input label="Address" wire:model="address" icon="o-home"/>
                <x-mary-datetime label="Date" wire:model="date" icon="o-calendar"/>
                <x-mary-datetime label="Start Time" wire:model="startTime" icon="o-clock" type="time"/>
                <x-mary-datetime label="End Time" wire:model="endTime" icon="o-clock" type="time"/>

                <label>Location</label>
                <div class="rounded" style="height: 400px" id="map"></div>

                @error('latitude')
                <x-input-error :messages="$message" />
                @enderror

                <x-slot:actions>
                    <x-mary-button link="{{ route('campaigns.index') }}" label="Cancel"/>
                    <x-mary-button label="Save!" class="btn-primary" type="submit" spinner="save"/>
                </x-slot:actions>
            </x-mary-form>
        </div>
    </div>
</div>

@script
<script>
    // 封装地图初始化函数
    function initMap(lat = 7.29312, lng = 80.63410) {
        // 先清除可能存在的地图实例
        if (window.mapInstance) {
            window.mapInstance.remove();
        }
        
        // 创建新地图实例
        window.mapInstance = L.map('map', {
            center: [lat, lng],
            zoom: 14,
            minZoom: 12,
            maxZoom: 14
        });
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {}).addTo(window.mapInstance);
        
        // 初始化标记,如果有坐标则添加
        window.markerInstance = L.marker([lat, lng]).addTo(window.mapInstance);

        // 地图点击事件
        window.mapInstance.on('click', function(e) {
            window.markerInstance.setLatLng(e.latlng);
            $wire.latitude = e.latlng.lat;
            $wire.longitude = e.latlng.lng;
        });
    }

    // 组件挂载时初始化地图
    document.addEventListener('livewire:init', function() {
        initMap(@this.latitude || 7.29312, @this.longitude || 80.63410);
    });

    // 监听组件刷新事件,重新初始化地图并恢复坐标
    Livewire.on('refresh', function() {
        setTimeout(() => {
            initMap(@this.latitude || 7.29312, @this.longitude || 80.63410);
        }, 100);
    });
</script>
@endscript

@assets
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
      integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
      crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
        integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
        crossorigin=""></script>
@endassets

关键说明

  • 使用window.mapInstance和window.markerInstance全局存储实例,避免刷新时丢失引用
  • initMap函数支持传入初始坐标,刷新时优先使用用户已选择的latitude和longitude
  • 通过livewire:init事件在组件首次挂载时初始化地图
  • 监听refresh事件,延迟重新初始化地图(确保DOM已完成更新)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 23:47:03