Vue2Leaflet Demo

by Michael Underwood

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue2-leaflet.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<body>
  <div id="app">
    <my-map :markers="markers">
      <template #markerpopup="{ marker, shouldShow }">
        <my-popup v-if="shouldShow" :marker="marker"></my-popup>
        <span v-else style="display:none;"/>
			</template>
    </my-map>
  </div>
</body>

CSS

html, body, #app {
  height: 100%;
  margin: 0;
}

JavaScript

var { LMap, LTileLayer, LMarker, LPopup } = Vue2Leaflet;

Vue.component('my-popup', {
	props: ['marker'],
  data() {
  	return {
      now: null,
    };
  },
  template: `<p>At {{now}}, {{marker.id}} is at {{marker.latlng.lat}}, {{marker.latlng.lng}}</p>`,
  mounted() {
    console.log("mounting my-popup");
  	this.now = new Date();
  },
});

Vue.component('my-map', {
  components: { LMap, LTileLayer, LMarker, LPopup },
	props: [
    'markers',
  ],
  data() {
    return {
      zoom:13,
      center: L.latLng(47.413220, -1.219482),
      url:'http://{s}.tile.osm.org/{z}/{x}/{y}.png',
      attribution:'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
      visiblePopups: {},
    };
  },
  computed: {
    hasPopupSlot () {
			return !!this.$scopedSlots.markerpopup;
		},
  },
  methods: {
		showPopup (id) {
      console.log('showing popup for ', id);
			this.$set(this.visiblePopups, id, true);
		},
		hidePopup (id) {
      console.log('hiding popup for ', id);
			this.$set(this.visiblePopups, id, false);
		},
  },
  template: `<l-map :zoom="zoom" :center="center">
      <l-tile-layer :url="url" :attribution="attribution"></l-tile-layer>
        <l-marker
          v-for="marker in markers"
          :key="marker.id"
          :lat-lng="marker.latlng"
        >
          <l-popup v-if="hasPopupSlot" @add="showPopup(marker.id)" @remove="hidePopup(marker.id)">
            <slot name="markerpopup" v-bind:shouldShow="!!visiblePopups[marker.id]" v-bind:marker="marker" />
          </l-popup>
        </l-marker>
    </l-map>`
});

new Vue({
  el: '#app',
  data() {
    return {
      markers: [
      	{ id: 'abc', latlng: L.latLng(47.413220, -1.219482) },
      ],
    }
  },
});