使用vue-google-maps套件實作地圖(二)


Posted by Akira on 2021-12-25

上回講完在網頁上放置地圖及 marker ,這回來講講如何放置多個 marker 及客製化地標資訊。

在地圖上放置多個 marker

這個簡單,只要在 data 中的 markers 放置一組的 position 陣列,並用 v-for 放到 template 中就可以囉!

<template>
  <GmapMap
    :center="center"
    :zoom="15"
    :options="options"
    style="width: 100%; height: 600px"
  >
    <GmapMarker
      v-for="(m,i) in markers"
      :key="i"
      :position="m.position"
      :clickable="false"
      :draggable="false"
    />
  </GmapMap>
</template>
<script>
export default {
  name: "AddGoogleMap",
  data() {
    return {
      markers: [
        { position: { lat: 25.033671, lng: 121.564427 } },
        { position: { lat: 25.0325917, lng: 121.5624999 } },
        // 可新增多個地點。
      ],
      center: { lat: 25.033671, lng: 121.564427 },
      options: {
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        fullscreenControl: false,
        disableDefaultUI: true,
        scrollwheel: true,
        clickableIcons: false,
      },
    };
  },
};
</script>

成果會長這樣:

放置地標資訊 ( InfoWindow )

<template>
    <GmapMap
      :center="center"
      :zoom="15"
      :options="options"
      style="width: 100%; height: 600px"
    >
      <GmapInfoWindow
        :position="infoWindowPos"
        :opened="infoWinOpen"
        :options="infoOptions"
        @closeclick="infoWinOpen = false"
      >
      </GmapInfoWindow>
      <GmapMarker
        v-for="(m, i) in markers"
        :key="i"
        :position="m.position"
        :clickable="true"
        :draggable="false"
        @click="toggleInfoWindow(m, i)"
      />
    </GmapMap>
</template>

我們先來介紹 GmapInfoWindow 的屬性。

  • position:要有地標資訊的地方。
  • opened:是否開啟地標。
  • options:主要有三個常用屬性。
    • maxWidth:設定最大寬度。
    • content:地標資訊的內容,支援 HTML 語法。
    • pixelOffset:位移多少 {width, height} 。
  • closeclick:按下關閉視窗時要做的動作。
    更多Map控制內容可以參考 Google Map 官方文件

我們來看看 data 的設定:

  data() {
    return {
      markers: [
        {
          position: { lat: 25.033671, lng: 121.564427 },
          infoText:
            "<div class='img'><img src='https://www.taiwan.net.tw/att/1/big_scenic_spots/pic_7927_32.jpg'  alt='台北101'></div><h4 style='font-size: 1rem;'>台北101</h4>",
        },
        {
          position: { lat: 25.0325917, lng: 121.5624999 },
          infoText: "<div class='img'><img src='https://photo.travelking.com.tw/scenery/1F8576A4-EFD5-494E-B117-9F89E5A9A9C6_e.jpg'  alt='捷運世貿站'></div><h4 style='font-size: 1rem;'>捷運世貿站</h4>",
        },
      ],
      center: { ... },
      options: { ... },
      infoWindowPos: null,
      infoWinOpen: false,
      currentIdx: null,

      infoOptions: {
        maxWidth: 200,
        content: "",
        pixelOffset: {
          width: 0,
          height: -40,
        },
      },
    };
  }

infoText:markers 中的每個項目都增加了 infoText ,表示之後要呈現的內容。
infoWindowPos:用來裝要呈現地標資訊的座標。
infoWinOpen:是否要開啟地標資訊。
currentiIdx:要開啟地標資訊的是誰。

補充:我有另外地標資訊中的圖片一組CSS。

.img {
    width: 150px;
    height: 120px;
    padding: 4px;
    overflow: hidden;
    img {
      height: 100%;
      width: auto;
    }

有了這些資訊之後,透過在 GmapMarker 上綁定 click 事件,便可以知道點擊的地點及Index資訊。

接著在 methods 新增 function toggleInfoWindow,點擊一次會開啟視窗,如果兩次都點擊同個地點,則會關閉視窗。

  methods: {
    toggleInfoWindow: function (marker, idx) {
      this.infoWindowPos = marker.position;
      this.infoOptions.content = marker.infoText;
      if (this.currentIdx == idx) {
        this.infoWinOpen = !this.infoWinOpen;
      } else {
        this.infoWinOpen = true;
        this.currentIdx = idx;
      }
    },
  },

鏘鏘——完成效果請看!

完整 script 請見以下:

<script>
export default {
  name: "AddGoogleMap",
  data() {
    return {
      markers: [
        {
          position: { lat: 25.033671, lng: 121.564427 },
          infoText:
            "<div class='img'><img src='https://www.taiwan.net.tw/att/1/big_scenic_spots/pic_7927_32.jpg'  alt='台北101'></div><h4 style='font-size: 1rem;'>台北101</h4>",
        },
        {
          position: { lat: 25.0325917, lng: 121.5624999 },
          infoText: "<div class='img'><img src='https://photo.travelking.com.tw/scenery/1F8576A4-EFD5-494E-B117-9F89E5A9A9C6_e.jpg'  alt='捷運世貿站'></div><h4 style='font-size: 1rem;'>捷運世貿站</h4>",
        },
      ],
      center: { lat: 25.033671, lng: 121.564427 },
      options: {
        mapTypeControl: false,
        scaleControl: false,
        streetViewControl: false,
        fullscreenControl: false,
        disableDefaultUI: true,
        scrollwheel: true,
        clickableIcons: false,
      },
      infoWindowPos: null,
      infoWinOpen: false,
      currentIdx: null,

      infoOptions: {
        maxWidth: 200,
        content: "",
        pixelOffset: {
          width: 0,
          height: -40,
        },
      },
    };
  },
  methods: {
    toggleInfoWindow: function (marker, idx) {
      this.infoWindowPos = marker.position;
      this.infoOptions.content = marker.infoText;
      if (this.currentIdx == idx) {
        this.infoWinOpen = !this.infoWinOpen;
      } else {
        this.infoWinOpen = true;
        this.currentIdx = idx;
      }
    },
  },
};
</script>

#google map API #Vue #Vue.js #vue2-google-maps #Front-End #前端







Related Posts

Python 字典 dict 和集合 set 入門教學

Python 字典 dict 和集合 set 入門教學

邪魔歪道還是苦口良藥?Functional CSS 經驗分享

邪魔歪道還是苦口良藥?Functional CSS 經驗分享

Tailwind CSS 安裝 VSCode 相關套件

Tailwind CSS 安裝 VSCode 相關套件


Comments