How to Integrate AMap API in Vue for Positioning and Custom Info Windows

This guide walks through registering an AMap application, installing vue‑amap, configuring the API loader, building a reusable Vue component with search, geolocation, custom markers and styled info windows, and embedding the component into a page to achieve full map display and positioning functionality.

The Dominant Programmer
The Dominant Programmer
The Dominant Programmer
How to Integrate AMap API in Vue for Positioning and Custom Info Windows

After setting up the RuoYi front‑end/back‑end project (see the linked CSDN tutorial), the next step is to add Gaode (AMap) map capabilities.

1. Register an AMap application

Log in to the AMap Open Platform, create a new Web application, and generate a key. The key will be used in the Vue configuration.

2. Install the Vue wrapper npm install vue-amap 3. Initialize the loader in main.js

<script>
import VueAMap from 'vue-amap'
Vue.use(VueAMap)
VueAMap.initAMapApiLoader({
  key: 'YOUR_AMAP_KEY',
  plugin: [
    'AMap.Scale',
    'AMap.OverView',
    'AMap.ToolBar',
    'AMap.MapType',
    'AMap.PlaceSearch',
    'AMap.Geolocation',
    'AMap.Geocoder'
  ],
  v: '1.4.4',
  uiVersion: '1.0'
})
</script>

4. Create the map component AMap.vue

The template defines a full‑size container, a search box, and buttons for manual search and positioning. The core map element is <el-amap> with bindings for manager, zoom, plugins, center, and events.

<template lang="html">
  <div style="width:100%;height:800px;">
    <div class="container">
      <div class="search-box">
        <input v-model="searchKey" type="search" id="search">
        <button @click="searchByHand">搜索</button>
        <div class="tip-box" id="searchTip"></div>
        <button @click="positionByHand">定位</button>
      </div>
      <el-amap
        :amap-manager="amapManager"
        :vid="'amap-vue'"
        :zoom="zoom"
        :plugin="plugin"
        :center="center"
        :events="events"
        class="amap-box">
        <el-amap-marker
          v-for="(marker, index) in carmarkers"
          :key="index"
          :position="marker.position"
          :vid="index"
          :content="marker.content"
          :events="marker.events"></el-amap-marker>
        <el-amap-info-window
          :position="currentWindow.position"
          :content="currentWindow.content"
          :visible="currentWindow.visible"
          :events="currentWindow.events">
        </el-amap-info-window>
      </el-amap>
    </div>
  </div>
</template>

<script>
import { AMapManager, lazyAMapApiLoaderInstance } from 'vue-amap'
let amapManager = new AMapManager()
export default {
  name: 'AMap',
  data() {
    return {
      carmarkers: [],
      currentWindow: { position: [116.396624, 39.908167], content: '111', events: {}, visible: false },
      address: null,
      searchKey: '',
      amapManager,
      markers: [],
      searchOption: { city: '全国', citylimit: true },
      center: [116.396624, 39.908167],
      zoom: 17,
      lng: 0,
      lat: 0,
      loaded: false,
      events: {
        init() {
          lazyAMapApiLoaderInstance.load().then(() => { this.initSearch() })
        },
        click(e) {
          this.markers = []
          const { lng, lat } = e.lnglat
          this.lng = lng
          this.lat = lat
          this.center = [lng, lat]
          this.markers.push([lng, lat])
          const geocoder = new AMap.Geocoder({ radius: 1000, extensions: 'all' })
          console.log(lng + "," + lat)
          geocoder.getAddress([lng, lat], (status, result) => {
            if (status === 'complete' && result.info === 'OK' && result && result.regeocode) {
              console.log(result.regeocode.formattedAddress)
              this.address = result.regeocode.formattedAddress
              this.searchKey = result.regeocode.formattedAddress
              this.$nextTick()
            }
          })
        }
      },
      plugin: [
        { pName: 'Geocoder', events: { init(o) {} } },
        { pName: 'Geolocation', events: { init(o) { o.getCurrentPosition((status, result) => {
          if (result && result.position) {
            this.lng = result.position.lng
            this.lat = result.position.lat
            this.center = [this.lng, this.lat]
            this.markers.push([this.lng, this.lat])
            this.loaded = true
            this.$nextTick()
          }
        }) } } },
        { pName: 'ToolBar', events: { init(instance) {} } },
        { pName: 'OverView', events: { init(instance) {} } },
        { pName: 'MapType', defaultType: 0, events: { init(instance) {} } },
        { pName: 'PlaceSearch', events: { init(instance) {} } }
      ]
    }
  },
  methods: {
    initSearch() {
      const vm = this
      const map = this.amapManager.getMap()
      AMapUI.loadUI(['misc/PoiPicker'], function(PoiPicker) {
        const poiPicker = new PoiPicker({
          input: 'search',
          placeSearchOptions: { map: map, pageSize: 10 },
          suggestContainer: 'searchTip',
          searchResultsContainer: 'searchTip'
        })
        vm.poiPicker = poiPicker
        poiPicker.on('poiPicked', function(poiResult) {
          const source = poiResult.source
          const poi = poiResult.item
          if (source !== 'search') {
            poiPicker.searchByKeyword(poi.name)
          } else {
            poiPicker.clearSearchResults()
            vm.markers = []
            const lng = poi.location.lng
            const lat = poi.location.lat
            const address = poi.cityname + poi.adname + poi.name
            vm.center = [lng, lat]
            vm.markers.push([lng, lat])
            vm.lng = lng
            vm.lat = lat
            vm.address = address
            vm.searchKey = address
          }
        })
      })
    },
    searchByHand() {
      if (this.searchKey !== '') {
        this.poiPicker.searchByKeyword(this.searchKey)
      }
    },
    positionByHand() {
      this.currentWindow = {
        position: [121.492439, 31.233264],
        content: `<div style="color: #1c84c6;">公众号:霸道的程序猿</div>`,
        events: { close: e => { this.currentWindow.visible = false } },
        visible: true
      }
      this.carmarkers = [{
        position: [121.492439, 31.233264],
        content: `<div><img width=50 height=50 src="https://images.cnblogs.com/cnblogs_com/badaoliumangqizhi/1539113/o_qrcode_for_gh_f76a8d7271eb_258.jpg" alt="汽车"></div>`,
        events: { click: e => { this.currentWindow = { position: this.center, content: `<div style="color: #1c84c6;">公众号:霸道的程序猿 </div>`, events: { close: ev => { this.currentWindow.visible = false } }, visible: true } } }
      }]
    }
  }
}
</script>

<style lang="css">
.container { width:100%; height:100%; position:relative; left:50%; top:50%; transform:translate3d(-50%,-50%,0); border:1px solid #999; }
.search-box { position:absolute; z-index:5; width:30%; left:13%; top:10px; height:30px; }
.search-box input { float:left; width:80%; height:100%; border:1px solid #30ccc1; padding:0 8px; outline:none; }
.search-box button { float:left; width:20%; height:100%; background:#30ccc1; border:1px solid #30ccc1; color:#fff; outline:none; }
.tip-box { width:100%; max-height:260px; position:absolute; top:30px; overflow-y:auto; background:#fff; }
</style>

5. Use the component in a page

import AMap from '@/components/Amap/AMap'
export default {
  name: 'index',
  components: { AMap }
}
<template>
  <div class="app-container home">
    <el-row :gutter="20">
      <AMap/>
    </el-row>
    <el-divider />
  </div>
</template>

The page now displays the map with search, geolocation, custom markers, and a styled info window. Additional features can be explored in the official AMap documentation.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

frontendVueMap IntegrationAmapgeolocationCustom Info Window
The Dominant Programmer
Written by

The Dominant Programmer

Resources and tutorials for programmers' advanced learning journey. Advanced tracks in Java, Python, and C#. Blog: https://blog.csdn.net/badao_liumang_qizhi

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.