Leaflet представляет собой низкоуровневую библиотеку для работы с интерактивными картами, предоставляющую слой управления тайлами, векторами, событиями и пользовательскими интеракциями. При интеграции с Vue-фреймворками появляется задача синхронизации императивной модели Leaflet с декларативной моделью компонентов.
В экосистеме Vue существуют две ключевые обёртки над Leaflet:
Обе библиотеки решают одну задачу — превращение Leaflet в набор реактивных компонентов, но различаются архитектурой, механизмами реактивности и способом работы с жизненным циклом карты.
Leaflet оперирует прямыми DOM-манипуляциями: карта создаётся через
L.map(), слои добавляются методом addLayer(),
события подписываются через on().
Vue, напротив, использует:
Интеграция требует мостового слоя:
Vue.js в версии 2 использует Object.defineProperty для реактивности. Это накладывает ограничения:
Vue2-leaflet строится вокруг этих ограничений.
Библиотека вводит компонентную абстракцию над Leaflet API:
<l-map> — контейнер карты<l-tile-layer> — слой тайлов<l-marker> — маркеры<l-popup> — всплывающие окна<l-polyline> / <l-polygon> —
геометрияКаждый компонент:
mountedbeforeDestroy<template>
<l-map
:zoom="13"
:center="[48.8566, 2.3522]"
style="height: 500px; width: 100%"
>
<l-tile-layer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
</l-map>
</template>
Внутри:
l-map вызывает L.map()l-tile-layer вызывает
L.tileLayer().addTo(map)<l-marker
v-for="point in points"
:key="point.id"
:lat-lng="[point.lat, point.lng]"
/>
Механизм работы:
lat-lngsetLatLng()Vue 3 использует Proxy-based реактивность, что радикально меняет подход:
Это упрощает интеграцию с Leaflet.
Vue3-leaflet активно использует Composition API:
setup() вместо Options APIref() и reactive() для состояния
картыonMounted() вместо mountedimport { ref, onMounted } from "vue";
import { LMap, LTileLayer, LMarker } from "vue3-leaflet";
export default {
components: { LMap, LTileLayer, LMarker },
setup() {
const center = ref([48.8566, 2.3522]);
const zoom = ref(13);
return { center, zoom };
}
};
Vue3-leaflet уменьшает необходимость ручных watchers:
Vue2-leaflet:
Vue3-leaflet:
Vue3-leaflet демонстрирует:
Vue2:
Vue3:
Vue3-leaflet:
Vue2-leaflet:
Leaflet предоставляет богатую систему событий:
clickmovezoomlayeraddlocationfound<l-map @click="handleClick" />
Под капотом:
map.on('click', handler)map.off при уничтожении компонента<LMap @click="handleClick" />
Разница:
Обе библиотеки используют стандартный подход:
<LTileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
Поддерживаются:
Vue3-leaflet добавляет более гибкую реактивность геометрии:
<LPolygon :lat-lngs="polygonPoints" />
Изменение массива автоматически обновляет геометрию.
В обеих версиях часто используется plugin-модель Leaflet:
Vue3-leaflet проще интегрируется с динамическими наборами данных:
mounted → создание mapbeforeDestroy → cleanuponMounted → инициализацияwatchEffect → автоматические обновленияonBeforeUnmount → очисткаЧасто используется глобальное состояние:
Vue3 удобнее интегрируется с:
Слои описываются как данные:
layers: [
{ type: "marker", coords: [...] },
{ type: "polygon", coords: [...] }
]
Vue превращает данные в визуальные элементы карты.
При росте количества объектов используются стратегии:
Vue3-leaflet лучше адаптируется к этим стратегиям за счёт более гибкой реактивной системы.
Типичный сценарий:
Leaflet поддерживает GeoJSON напрямую:
L.geoJSON(data).addTo(map);
Vue3-leaflet чаще использует реактивную обёртку над этим процессом, где данные обновляются автоматически при изменении store.
Leaflet работает с:
[lat, lng]Vue-обёртки добавляют слой абстракции:
Vue2-leaflet:
Vue3-leaflet:
Leaflet позволяет создавать UI элементы поверх карты:
Vue2:
Vue3: