SoFunction
Updated on 2025-04-09

Best practices for Vue to develop Gaode Map Application

Preface

I have not done many product systems about map interaction before. Currently, there are only a few mainstream map application SDKs in China: Gaode, Baidu and Tencent. So I personally think that Gaode map development is relatively better in PC applications, at least there is no obvious pitfall to experience. This article is a summary of the development map application.

Asynchronous loading

Because using the js sdk application, the script file itself is very large, so you should pay attention to the loading time of white screen to solve the user experience problem. Currently, most product applications are SPA single-page application systems, so I encapsulate an asynchronous loading method:

const loadScripts = async scripts => {
  const get = src => {
    return new Promise(function(resolve, reject) {
      const el = ('script')
      ('load', function() {
        resolve(src)
      }, false)
      ('error', function() {
        reject(src)
      }, false)
       = 
       = 
      ('body')[0].appendChild(el) || ('head')[0].appendChild(el)
    })
  }

  const myPromises = (async script => {
    if (() === null) {
      return await get(script)
    }
  })

  return await (myPromises)
}

export default loadScripts

When loading the script, this method first determines whether the script exists on the page. If it exists, it will not be loaded a second time, and then use the load callback to execute the relevant methods.

Package components

If there are multiple pages in the system that require map application services, then you need to encapsulate a general map component to improve project maintainability. I will simply encapsulate the map application here:

<template>
  <div
    :style="{
      width: width,
      height: height
    }"
    class="amap-container"
  >
    <div ref="amap" class="amap">
      <slot />
    </div>
  </div>
</template>

<style lang="scss" scoped>
    .amap-container {
    .amap {
        width: 100%;
        height: 100%;
    }
    }
</style>

Specify a map application container, which wraps a layer outside to specify the height and width. The height and width are passed in as external variables. The business logic is as follows:

import loadScripts from '@/loadScripts'
export default {
  name: 'AMapContainer',
  props: {
    width: {
      require: false,
      type: String,
      default: '100%'
    },
    height: {
      require: false,
      type: String,
      default: '600px'
    },
    options: {
      require: false,
      type: Object,
      default: () =&gt; {}
    }
  },
  data: () =&gt; ({
    amap: null,
    amapInfo: {
      key: 'xxxxxxxxxxxxxx'
    }
  }),
  created() {
    ()
  },
  beforeDestroy() {
    // Destroy the map    if (!) {
      return
    }
    ()
     = null
  },
  methods: {
    initAMap() {
      loadScripts([{
        id: 'ampa',
        url: `/maps?v=2.0&amp;key=${}&amp;plugin=`
      }]).then(() =&gt; {
         = new (this.$refs['amap'], )
        this.$emit('map', , )
      })
    }
  }
}

Initialize the map container when the application is loaded: load Gaode map js sdk asynchronously, then instantiate the map application in the callback method, and pass the instantiated object of the map into the $emit event, which is convenient for the parent component to need. Also, be careful to destroy the map application during the destruction life cycle, otherwise it will occupy a large amount of system memory.

Usage Components

After encapsulating the components, you can introduce components on the corresponding page to use:

&lt;template&gt;
    &lt;amap-container height="100%" :options="amapOptions" @map="getAMapData" /&gt;
&lt;/template&gt;

&lt;script&gt;
    import AMap from '@/components/AMap'

    export default {
        name: 'AMapDemo',
        components: {
            'amap-container': AMap
        },
        data: () =&gt; ({
            amapOptions: {
                zoom: 14,
                resizeEnable: true,
                viewMode: '3D',
                mapStyle: 'amap://styles/normal'
            },
            AMap: null, // Map object            amap: null // Current map instance        }),
        methods: {
            /**
              * Callback after the map is loaded
              * @param amap
              * @param AMap
              */
            getAMapData(amap, AMap) {
                // Get the map amap object from the component                 = amap
                // Get map AMap static object from component                 = AMap
            }
        }
    }
&lt;/script&gt;

Then launch related business based on the above. For map applications, the most core data is the coordinates in map applications. Whether it is the map marking elements, line elements (trajectory, etc.), drawing elements, etc., you only need to obtain the corresponding latitude and longitude data and store it in the database. As for how to obtain it, I will not explain in detail here.

Custom interface best practices

The map application I made before was created, in the detailed interface of the mark (select a mark to open the interface with the left button). This interface needs to be passed into the native document object, but this writing method does not conform to the vue object, so many systems have spent a lot of time writing dom structures before, which is a headache. In order to solve this problem, is there a related method in vue to mount components to obtain the real document object? After reviewing the relevant documents, there is indeed this API: . Use this API to mount component objects to obtain the instantiated component objects.

import ContextCard from './components/ContextCard'

// Create tagsconst marker = new ({
  map: ,
  position: [119.058904, 33.537069]
})
// Bind click event('click', )

// Click to open the pop-up windowconst markerInfoWindow = () =&gt; {
  // Introduce Vue component constructor instantiation  const ContextCardContent = (ContextCard)
  // Mount components  const contextCardContent = new ContextCardContent().$mount()
  // Instantiate the window object   = new ({
    isCustom: true,
    content: contextCardContent.$el,
    offset: new (0, -40)
  })
  // Open the window  (, ())
  // Close window of listening to component events  contextCardContent.$on('closeWindow', () =&gt; ())
}

Components:

&lt;template&gt;
  &lt;el-card class="context-box-card box-card"&gt;
    &lt;div slot="header" class="header"&gt;
      &lt;span&gt;Card name&lt;/span&gt;
      &lt;el-button type="text" class="close-btn" @click="closeWindow"&gt;closure&lt;/el-button&gt;
    &lt;/div&gt;
    &lt;div v-for="o in 4" :key="o" class="text item"&gt;
      {{ 'List Content' + o }}
    &lt;/div&gt;
  &lt;/el-card&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
  name: 'AMapContextCard',
  methods: {
    closeWindow() {
      this.$emit('closeWindow')
    }
  }
}
&lt;/script&gt;

&lt;style lang="scss" scoped&gt;
.context-box-card {
  width: 320px;
  height: 200px;

  .header {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }

  ::v-deep .el-card__header {
    padding: 5px 20px;
  }
}
&lt;/style&gt;

The above is the detailed information of a punctuation click to open a tag pop-up window, and the component is instantiated using the constructor. This greatly improves the robustness of the project.

import Vue from "vue";
import App from "./";

import Element from "element-ui";

import "/";
import "element-ui/lib/theme-chalk/";

 = false;

(Element);

new Vue({
  render: (h) => h(App)
}).$mount("#app");

Summarize

This is the end of this article about Vue developing the Gaode Map application. For more related content of Vue Gaode Map application, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!