JSFiddle - React, Tailwind, and code Playground

by Michael Underwood

HTML

<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css">
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script src="https://unpkg.com/[email protected]/dist/vue2-leaflet.js"></script>
<body>
  <div id="app">
    <div class="quarter">
      <!-- Layer is rendered from a single async definition: Works -->
      <v-map v-if="singleAjax.url" :zoom="zoom" :center="center" :options='{zoomControl: false}'>
        <v-tilelayer :url="singleAjax.url" :attribution="singleAjax.attribution"></v-tilelayer>
      </v-map>
    </div>
    <div class="quarter">
      <!-- Layer is rendered for each element of a synchronous one-element array: Works -->
      <v-map :zoom="zoom" :center="center" :options='{zoomControl: false}'>
        <v-tilelayer v-for="(layer, index) in baseLayers" :key="index" :url="layer.url" :attribution="layer.attribution"></v-tilelayer>
      </v-map>
    </div>
    <div class="quarter">
      <p>
        Above: Map from single layer definition loaded asynchronously (async, no <code>v-for</code>).
        <span v-if="!singleAjax.attribution">(Not loaded yet)</span>
      </p>
      <p>
        Above-right: Map from synchronous layer array (uses <code>v-for</code>, not async)
      </p>
      <p>
        Right: Map from async layer array (uses <code>v-for</code> and async).
        <span v-if="!ajaxLayers.length">(Not loaded yet)</span>
        <span v-else>(Attribs: <span v-for="(layer, index) in ajaxLayers" :key="index">{{ layer.attribution }}</span>)</span>
      </p>
      <!-- List contents are rendered from async array: Works -->
      <h3>
        Loaded layers
      </h3>
      <ul v-if="ajaxLayers.length || singleAjax.attribution">
        <li v-if="singleAjax.attribution">{{ singleAjax.attribution }}</li>
        <li v-for="(layer, index) in ajaxLayers" :key="index">{{ layer.attribution }}</li>
      </ul>
      <p...

CSS

html, body, #app {
  height: 100%;
  margin: 0;
}
.quarter {
  height: 50%;
  width: 50%;
  float: left;
}

JavaScript

Vue.component('v-map', Vue2Leaflet.LMap);
Vue.component('v-tilelayer', Vue2Leaflet.LTileLayer);

new Vue({
  el: '#app',
  data() {
    return {
      zoom: 13,
      center: [51.5, 0],
      baseLayers: [
      	{
      		url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        	attribution: 'Hard-coded layer array',
      	}
      ],
      singleAjax: {},
      ajaxLayers: []
    }
  },
  mounted () {
      window.setTimeout(this.addOneLayer, 2000)
  	  window.setTimeout(this.addLayers, 4000)
  },
  methods: {
    addLayers () {
      this.ajaxLayers.push({
        url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        attribution: 'Ajax Layer Array',
      })
    },
    addOneLayer () {
      this.singleAjax = {
        url: 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        attribution: 'One Ajax Layer',
      };
    }
  }  
});