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
相关产品推荐
相关产品推荐

