Vue Google Maps InfoWindow的自定义按钮不起作用

时间:2018-11-22 16:39:53

标签: javascript google-maps vue.js vuejs2 vue2-google-maps

嗨,伙计们!

我正在使用vue2-google-maps的所有功能,到目前为止,除了信息窗口中的自定义按钮外,我已经做了很多事情。到目前为止,我可以单击一个标记,它会显示具有正确信息的相关自定义信息窗口。我现在唯一想念的就是使这些按钮起作用。例如,关闭按钮:我可以单击它,它与component方法有关,但不会将其关闭。关闭按钮的作用与选择标记相同,但同时不是吗?这些值会更新为false,但不会在地图中更新,而我选择的标记会像吊饰一样更新。所以我很困惑,很困惑,任何帮助,想法和技巧都值得赞赏!

这是我的参考代码:

模板

<gmap-map
    id="map"
    :center="center"
    :zoom=13
    :options="{
        disableDefaultUI: true,
        zoomControl: true,
        clickableIcons: true,
    }">

    <gmap-marker
        v-for="(location, index) in locations"
        :position="{lat: location.latitude, lng: location.longitude}"
        :icon="location.icon"
        :zone="location.zone"
        :jettyNumber="location.jettyNumber"
        :selected="location.selected"
        :zIndex="location.zIndex"
        @mouseover="mouseOverMarker(index)"
        @mouseout="mouseOutMarker(index)"
        @click="openInfoWindow(index)"
        :label="{
            text: location.jettyNumber.toString(),
            color: '#fff',
            fontSize: '13px',
            fontFamily: 'din_round_otbold'
        }">

        <gmap-info-window
            :opened="location.infoBoxOpen">
                <div class="infoWindow" style="width: 300px;">
                    <div id="dock-zone" :class="getZoneClass(location.zone)">{{ getZoneClassText(location.zone) }}</div>
                    <h2 id="infoWindow-location">{{ location.name }}</h2>
                    <div id="close-btn" @click="closeInfoWindow(index)"></div>
                    <a class="btn btn-primary google-maps-infowindow-button">Kies als <b>{{ inputData.label }}</b></a>
                    <span></span>
                </div>
        </gmap-info-window>
    </gmap-marker>
</gmap-map>

组件脚本

import $ from "jquery";
export default {
data: function(){
    return {
        icons: {
            stopInner: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_inner.svg'
            },
            stopOuter: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_outer.svg'
            },
            stopOutside: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_outside.svg'
            },
            stopSelected: {
                icon: process.env.VUE_APP_PUBLIC_URL + '/Assets/images/pinpoint_on_map_active.svg'
            }
        },
        locations: [],
        center: {lat: 51.9004, lng: 4.46849},
        inputData: {}
    };
},
methods: {
    initMap(locations, inputData) {
        // Set maps specific data
        for(var i = 0; i < locations.length; i++) {
            locations[i].selected = false;
            locations[i].infoBoxOpen = false;
            locations[i].zIndex = locations[i].jettyNumber;
            locations[i].icon = this.getIcon(locations[i].zone);
        }
        this.inputData = inputData;
        this.locations = locations;
    },
    getIcon(zone) {
        switch(zone){
            case "centre":
                return this.icons.stopInner.icon;
            break;
            case null:
                return this.icons.stopOutside.icon;
            break;
            default:
                return this.icons.stopOuter.icon;
            break;
        }
    },
    getZoneClass(zone) {
        switch(zone){
            case "centre":
                return "centrum";
            break;
            case null:
                return "buiten";
            break;
            default:
                return "";
            break;
        }
    },
    getZoneClassText(zone) {
        if(zone){
            return zone;
        }else{
            return "outside";
        }
    },
    // TODO: Not really setting the zindex, need to dig deeper
    mouseOverMarker(locationIndex) { 
        this.locations[locationIndex].zIndex = 99998;
    },
    mouseOutMarker(locationIndex) { 
        this.locations[locationIndex].zIndex = this.locations[locationIndex].jettyNumber; 
    },
    openInfoWindow(location){
        this.center = {lat: location.latitude, lng: location.longitude};
        this.setSelectedLocation(location);
    },
    setSelectedLocation(selectedLocationIndex){
        this.unselectLocations();
        // Set selected
        this.locations[selectedLocationIndex].zIndex = 88888;
        this.locations[selectedLocationIndex].icon = this.icons.stopSelected.icon;
        this.locations[selectedLocationIndex].selected = true;
        this.locations[selectedLocationIndex].infoBoxOpen = true;
        this.center = {
            lat: this.locations[selectedLocationIndex].latitude,
            lng: this.locations[selectedLocationIndex].longitude
        };
        this.alterDefaultInfoWindowStyle();
    },
    unselectLocations() {
        for(var i = 0; i < this.locations.length; i++) {
            this.locations[i].icon = this.getIcon(this.locations[i].zone);
            this.locations[i].zIndex = this.locations[i].jettyNumber;
            this.locations[i].selected = false;
            this.locations[i].infoBoxOpen = false;
        }
    },
    alterDefaultInfoWindowStyle() {
        // TODO: a very nasty fix, need a better way to handle this
        setTimeout(function(){
            var iwOuter = $('.gm-style-iw');
            iwOuter.parent().parent().css({ top: '20px' });
            iwOuter.css({ top: '0px' });
            iwOuter.css({ left: '26px' });

            var iwBackground = iwOuter.prev();
            iwBackground.css({ 'display': 'none' });
            var iwCloseBtn = iwOuter.next();

            iwCloseBtn.hide();
            iwOuter.children().eq(0).css({ overflow: 'visible' });
        }, 10);
    },
    closeInfoWindow(selectedLocationIndex) {
        this.unselectLocations();
    },
    closeMaps() {
        this.$emit('close-maps')
    }
}

}

1 个答案:

答案 0 :(得分:0)

由于信息窗口的外观由locations[index].infoBoxOpen决定,因此也需要实现标准关闭处理程序(@closeclick),如下所示:

 <gmap-info-window
        :opened="location.infoBoxOpen"
        @closeclick="location.infoBoxOpen=false">
    ...
 </gmap-info-window>  

我还建议修改信息窗口的创建方式。无需为每个标记创建信息窗口,而仅创建一个信息窗口实例。除了提高性能外,还可以更加清晰地管理信息窗口状态,例如:

<gmap-map :center="center" :zoom="zoom" ref="map">
  <gmap-marker
    :key="index"
    v-for="(location,index) in locations"
    :position="{lat: location.lat,lng:location.lng}"
    :clickable="true"
    @click="openInfoWindow(location)"
  />
  <gmap-info-window v-if="selectedLocation !== null" :position="{lat: selectedLocation.lat,lng:selectedLocation.lng}" :opened="infoBoxOpen" @closeclick="closeInfoWindow()">
      <div class="infoWindow">
        <h2 id="infoWindow-location">{{ selectedLocation.name }}</h2>
        <button @click="closeInfoWindow()">Close</button>
      </div>
    </gmap-info-window>
</gmap-map>

export default {
  data: () => ({
    zoom: 5,
    center: { lat: 59.339025, lng: 18.065818 },
    selectedLocation: null,
    infoBoxOpen: false,
    locations: [
      {
        Id: 1,
        name: "Oslo",
        lat: 59.923043,
        lng: 10.752839
      },
      {
        Id: 2,
        name: "Stockholm",
        lat: 59.339025,
        lng: 18.065818
      },
      {
        Id: 3,
        name: "Copenhagen",
        lat: 55.675507,
        lng: 12.574227
      },
      {
        Id: 4,
        name: "Berlin",
        lat: 52.521248,
        lng: 13.399038
      },
      {
        Id: 5,
        name: "Paris",
        lat: 48.856127,
        lng: 2.346525
      }
    ]
  }),
  methods: {
    openInfoWindow(location) {
      this.selectedLocation = location
      this.infoBoxOpen = true;
    },
    closeInfoWindow() {
      this.infoBoxOpen = false;
    }
  }
};    

Here is a demo演示了如何管理多个标记的信息窗口