Vue2Leaflet中通过其他组件切换地图GeoJSON图层可见性
Hey there! Let's break down why your map layers aren't toggling when you select a date, and how to fix it step by step.
The Core Problem
Your issue boils down to Vue's reactivity system not detecting changes to your visible properties:
- The
dataobject in yourgeojson.jsis a plain JavaScript object, not a Vue reactive object. When you modify itsvisibleproperties, Vue has no way to track those changes. - Your component's
yesterday.dayandtoday.dayare static initial values copied from the externaldataobject—they don't automatically sync when the externalvisibleproperties change.
Step-by-Step Solution
1. Make Your GeoJSON Data Reactive
First, we need to ensure your map data is part of Vue's reactivity system. You have two options:
Option A: Move Data Into Component's Reactive data()
// In your MapView2 component's script data(){ return { zoom: 13, center: { lat: '', lng: '' }, url:'https://api.mapbox.com/styles/v1/mapbox/light-v9/tiles/256/{z}/{x}/{y}?access_token=...', attribution: '', // Move your GeoJSON data here to make it reactive mapData: { today: { "type": "FeatureCollection", "id": "0520", // Ensure this ID is unique from yesterday's "visible": false, "features": [ /* your features */ ] }, yesterday: { "type": "FeatureCollection", "id": "0519", // Fix: Use a different ID for yesterday "visible": true, "features": [ /* your features */ ] } }, // Extract options to keep things clean layerOptions: { onEachFeature: onEachFeature, color: "#45B8FF", fillOpacity: 0.8 } } }
Option B: Convert External Data to Reactive
If you want to keep your data in geojson.js, use Vue.observable() to make it reactive:
// In geojson.js import Vue from 'vue'; export const EventBus2 = new Vue(); export const data = Vue.observable({ today: { /* ... */ }, yesterday: { /* ... */ } }); // In your component's script import { data as mapData, EventBus2 } from '../assets/geojson/sample-geojson.js'; // Then use mapData directly in your component
2. Update Template Bindings
Modify your template to directly bind to the reactive visible properties:
<template> <div id="MapView2"> <i class="material-icons geoLocate" v-on:click="geoLoc">location_searching</i> <l-map :zoom="zoom" :options="{ zoomControl: false }" class="map" :center="center"> <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer> <!-- Bind directly to reactive visible properties --> <l-geo-json :visible="mapData.yesterday.visible" :geojson="mapData.yesterday" :options="layerOptions"></l-geo-json> <l-geo-json :visible="mapData.today.visible" :geojson="mapData.today" :options="layerOptions"></l-geo-json> </l-map> </div> </template>
3. Fix EventBus Listener Logic
Update your mounted hook to modify the reactive visible properties directly—Vue will detect these changes and update the map:
mounted() { EventBus2.$on('mapDay', pickerValue => { switch (pickerValue) { case this.mapData.today.id: this.mapData.yesterday.visible = false; this.mapData.today.visible = true; break; case this.mapData.yesterday.id: this.mapData.yesterday.visible = true; this.mapData.today.visible = false; break; } }); }
4. Optional: Add Watchers for Extra Logic
If you need to run additional code when layer visibility changes (like logging or manual map adjustments), add a watcher:
watch: { 'mapData.yesterday.visible'(newVisibility) { console.log('Yesterday layer visibility:', newVisibility); // Optional: Force map refresh if needed (add ref="map" to your l-map component) // this.$refs.map.mapObject.invalidateSize(); }, 'mapData.today.visible'(newVisibility) { console.log('Today layer visibility:', newVisibility); } }
Quick Note on IDs
In your original geojson.js, both today and yesterday have the same id: "0520"—this will break your switch statement! Make sure each date's ID is unique (e.g., yesterday as "0519", today as "0520") so the toggle works correctly.
内容的提问来源于stack exchange,提问作者omerkocaaga

