Riot.js предоставляет легковесный и реактивный способ создания пользовательских интерфейсов. При работе с картографическими библиотеками важно учитывать структуру компонентов, реактивность данных и эффективное управление состоянием карты.
Для большинства популярных библиотек, таких как Leaflet или Mapbox,
требуется подключение CSS и JS файлов через <script>
и <link> в HTML-шаблоне либо через npm. В
Riot-компоненте подключение обычно выполняется в блоке
onMounted, чтобы гарантировать, что DOM готов к
инициализации карты.
import { onMounted, onUnmounted } from 'riot';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
export default {
onMounted() {
this.map = L.map(this.root.querySelector('.map-container')).setView([55.751244, 37.618423], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(this.map);
},
onUnmounted() {
if (this.map) this.map.remove();
}
}
Ключевые моменты:
onMounted обеспечивает корректную инициализацию после
рендера DOM.onUnmounted нужен для очистки ресурсов и предотвращения
утечек памяти.this.root.querySelector позволяет
работать с элементом карты внутри компонента.Riot.js поддерживает реактивные свойства, что позволяет автоматически
обновлять маркеры и слои при изменении данных. Внутри компонента можно
создать реактивный массив markers и следить за его
изменениями:
this.markers = [];
this.addMarker = (lat, lng, popupText) => {
const marker = L.marker([lat, lng]).addTo(this.map);
if (popupText) marker.bindPopup(popupText);
this.markers.push(marker);
}
this.clearMarkers = () => {
this.markers.forEach(marker => marker.remove());
this.markers = [];
}
Особенности работы с Riot.js:
this.update().update(), если нужно синхронизировать отображение данных в
компоненте.При получении данных с сервера или взаимодействии с пользователем важно обновлять карту без полной перерисовки компонента. Riot.js позволяет манипулировать картой напрямую через методы библиотек. Пример динамического центрирования карты и изменения зума:
this.setView = (lat, lng, zoom = 12) => {
if (this.map) {
this.map.setView([lat, lng], zoom);
}
}
Реактивность Riot.js в данном случае используется не для перерисовки DOM, а для управления состоянием компонентов и передачи новых координат.
Карты часто требуют обработки кликов, перемещений и других событий.
Riot.js позволяет добавлять слушатели в onMounted и удалять
их в onUnmounted:
this.onMapCl ick = (e) => {
console.log('Клик по карте', e.latlng);
}
onMounted(() => {
this.map.on('click', this.onMapClick);
});
onUnmounted(() => {
this.map.off('click', this.onMapClick);
});
Важно:
Riot.js не ограничивает использование сторонних библиотек, но
важно соблюдать жизненный цикл компонентов. Любая
библиотека, манипулирующая DOM, должна инициализироваться в
onMounted. Для реактивного взаимодействия с данными
рекомендуется:
this.update() после изменения реактивных
свойств.this.map, this.markers).onUnmounted.import { onMounted, onUnmounted } from 'riot';
import L from 'leaflet';
import 'leaflet/dist/leaflet.css';
export default {
markers: [],
onMounted() {
this.map = L.map(this.root.querySelector('.map-container')).setView([55.751244, 37.618423], 10);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png').addTo(this.map);
this.map.on('click', (e) => {
this.addMarker(e.latlng.lat, e.latlng.lng, `Координаты: ${e.latlng.lat}, ${e.latlng.lng}`);
});
},
onUnmounted() {
if (this.map) this.map.remove();
},
addMarker(lat, lng, popupText) {
const marker = L.marker([lat, lng]).addTo(this.map);
if (popupText) marker.bindPopup(popupText);
this.markers.push(marker);
this.update();
},
clearMarkers() {
this.markers.forEach(marker => marker.remove());
this.markers = [];
this.update();
}
}
Такой подход обеспечивает гибкое управление картой, реактивные обновления маркеров и безопасное освобождение ресурсов, полностью используя возможности Riot.js и сторонних картографических библиотек.