首页 > 解决方案 > vue.js + v-ymap:在所选城市显示标记。并将地图置于所选城市的中心

问题描述

我想使用 vue.js 和 v-ymap 组件创建 yandex 地图。地图也有一个select包含城市列表的地图。在此选择城市后,select我的地图应以城市坐标为中心。并且城市的标记也应该被放置。

我编写了placeMarks(marks)为我的标记填充数据的方法。第一次一切都好:地图充满了标记并在我想要的地方居中。

但是当我选择另一个城市select时,地图没有任何反应。控制台中的错误:

vendor.js?id=30ec419b9ac7ad43a81f:3416 [Vue 警告]:无效的道具:道具“属性”的自定义验证器检查失败。

在发现

---> 在 npm/src/assets/components/EcoMap.vue

它链接到我清理标记字段(this.markers = [];)的行。但是,如果我删除了此代码行,则控制台中的错误链接到带有循环的行(请参见下面的 placeMark() 方法中的代码)。所以我认为我使用了完全错误的方法......

我的代码:

<template lang="pug">
  .delivery-sdek.eco-map
    .container
      h3 Найди свою аптеку
      .row
        .col-sm-6
          select(v-model="curCity")
            option(
              v-for="city in Doption"
              :value ="city.value"
              :name = "city.label"
              :selected ="city.value == '13330'"
              :disabled ="dsbl == 1"
            ) {{ city.label }}

    .delivery-sdek__map-canvas(:class="{'noPoints': noPoints !== null}")
      v-ymap(
        v-if="settings.coords"
        :center="settings.coords"
        :coords="settings.coords"
        :zoom="settings.zoom"
        :YMAPS_KEY="settings.apiKey"
        :behaviors=["drag", "dblClickZoom", "rightMouseButtonMagnifier", "multiTouch"]
      )
        v-ymap-placemark(
          v-if="markers.length>0"
          v-for="marker in markers"
          v-bind:key="marker.id"
          :geometry="marker.coords"
          :properties="{'balloonContentBody': marker.balloonContentBody}"
          :options="{iconLayout:'default#image', iconImageHref: '/images/icons/map-pin.svg', iconImageSize: [40, 52], iconImageOffset: [-15, -38]}"
        )
</template>
<script>
export default {
  name: 'EcoMap',
  data: function() {
    return {
      settings: {
        apiKey: "my-api",
        coords: [37.622216, 55.753918],
        zoom: 12
      },
      markers: [],
      lat: 0,
      lng: 0,
      noPoints: null,
      curCity: null,
      Doption: null,
      obResponse: null,
      dsbl: 0
    };
  },
  props: {
    api_key : {
      type: String,
      default: null
    },
    options: null

  },
  methods: {
    placeMarks(marks) {
      let $this = this;
      this.markers = [];
      this.lat = 0;
      this.lng = 0;
          $this.noPoints = null;
          marks.forEach(obj => {
            let newString = '<div class="map-info map-info_on-map"><div class="map-info__in">';
            newString += '<div class="map-info__header">' + '<p>' + obj.Name + '</p>' + '</div>' +
                '<div class="text text_black map-info__address">' + '<p>' + obj.Address;
            newString += '</p>' + '</div>';

            if (obj.WorkTime) {
              newString += '<div class="text text_black map-info__time">' + '<p>' + obj.WorkTime + '</p>' + '</div>';
            }
            if (obj.Phone) {
              newString += '<div class="text text_black map-info__phone">' + '<a href="tel:' + obj.Phone + '">' +
                  obj.Phone + '</a>' + '</div>';
            }

            $this.lat += parseFloat(obj.cY);
            $this.lng += parseFloat(obj.cX);

            $this.markers.push({
              id: obj.id,
              coords: [obj.cY, obj.cX],
              clusterCaption: obj.Name,
              balloonContentheader: '',
              balloonContentBody: newString,
              balloonContentFooter: '',
              hintContent: '',
              PVZaddr: obj.FullAddress,
              PVZ_city: obj.City
            });
          })

          let midLat = $this.lat / $this.markers.length;
          let midLng = $this.lng / $this.markers.length;
          $this.settings.coords = [midLat.toFixed(6), midLng.toFixed(6)];

    }
  },
  mounted() {
    this.Doption = JSON.parse(this.options);
    this.curCity = this.Doption[0].value;
    let formData = new FormData;
    formData.append('city', this.curCity);
    axios.post('/ajax/get-eco-boxes/', formData).then(response => {
      this.placeMarks(response.data);
    }).catch(response => {
      console.log(response);
    });
  },
  watch: {
    curCity: function (newCity, oldCity) {
      this.dsbl = 1;
      let formData = new FormData;
      formData.append('city', newCity);
      axios.post('/ajax/get-eco-boxes/', formData).then(response => {
        this.placeMarks(response.data);
        this.dsbl = 0;
      }).catch(response => {
        console.log(response);
        this.dsbl = 0;
      });

    }
  }
};
</script>

<style scoped>

</style>

你能帮忙解决这个问题吗?

A将不胜感激任何建议

标签: vue.jsmapsyandex-maps

解决方案


它只需要 :key param:

  v-ymap(
    :key="updKey"
    v-if="settings.coords"
    :center="settings.coords"
    :zoom="settings.zoom"
    :YMAPS_KEY="settings.apiKey"
    :behaviors=["drag", "dblClickZoom", "rightMouseButtonMagnifier", "multiTouch"]
  )

推荐阅读