Vue 3,传单:地图容器已经初始化

Vue 3, leaflet: Map container is already initialized

我意识到issue和classicjavascript是一样的。但是,我的目标是使用 v-for"'map'+user.id":ref 为每个 bootstrap 卡片动态创建经度、纬度传单地图。我想知道如何在 vue 3 中解决这个问题。

从控制台,我确认每个块可以有不同但相同的 ID class。

我发现这个 post with vuejs2 when initiating multiple instances. It's been a while, now the docs 说明了在方法中使用 ref 的正确方法。

这里是CodeSandBox。 (尽管在本地主机中呈现)

相关代码如下:

<template>
  <div class="container">
    <div class="row">
      <div class="col-md-4 mb-3" v-for="user in users" :key="user.id">
      <div :id="'map'+user.id" :ref="setItemRef" class="map"></div> 
    </div>
  </div>
</template>

<script>
import users from '@/data/data.js'
import L from 'leaflet'

export default {
  data() {
    return {
      status: true,
      users: [],
      map: null,
      accessToken: "Token shown in the CodeSandBox"
    }
  },
methods: {
setItemRef(el) {
      if (el) {
        // reference: https://v3.vuejs.org/guide/migration/array-refs.html#migration-strategy
        // this.itemRefs.push(el)
        console.log(el)
        this.map = L.map(el).setView([51.505, -0.09], 13);
        L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
            attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
            maxZoom: 18,
            id: 'mapbox/streets-v11',
            tileSize: 512,
            zoomOffset: -1,
            accessToken: this.accessToken
        }).addTo(this.map);
        // this.map.off()
        // this.map.remove()
        //console.log(this.map)
      }
    },
},
</script>

<style>
.map {
  width: 400px;
  height: 400px;
}
</style>

我这样做的方法是将 'map'+user.id 推入一个数组。然后使用 forEach 渲染不同的地图。我遇到的错误是因为 this.map 总是引用同一个实例。

因此,脚本中的代码应该是:

<script>
  export default {
  data() {
    return {
      status: true,
      users: [],
      itemRefs:[], // for saving the unique mapid
      accessToken: "Your mapbox token"
    }
  },
  methods: {
    /**
     * instantiate the id to each user to further use
     */
    instantiateId() {
      this.users.map((user,index) => user.id = index)
    },
    setItemRef(el) {
      if (el) {
        // reference: https://v3.vuejs.org/guide/migration/array-refs.html#migration-strategy
        //console.log(el)
        //console.log(el.id)
        this.itemRefs.push(el.id)
      }
    },
    createMap() {
      this.itemRefs.forEach(element => {
        // console.log(element)
        var mymap = L.map(element).setView([51.505, -0.09],13);
        L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
          attribution: 'Map data &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
          maxZoom: 18,
          id: 'mapbox/streets-v11',
          tileSize: 512,
          zoomOffset: -1,
          accessToken: this.accessToken
        }).addTo(mymap);
      });
    }
  },  
  mounted() {
    this.createMap()
  },
}
</script>