vue3中使用高德地图

原创
2022/01/06 09:48
阅读数 3.7K

vue3中使用高德地图

地图文档地址:https://vue-amap.guyixi.cn/
仓库地址:https://gitee.com/guyangyang/vue-amap

插件介绍

[@vuemap/vue-amap@next](https://vue-amap.guyixi.cn/)插件是在vue-amap基础上重新处理封装,vue版本升级为3.0,事件绑定方式调整为v-on,支持typescript,支持IDE提示(webstorm和vscode),支持tree-shaking,对高德可视化组件loca进行封装,提供默认的图层样式处理。

组件优势

  • 支持vue2、vue3,0.0.x版本支持vue2,1.0.x版本支持vue3
  • 所有事件使用v-on方式绑定,更接近于vue开发习惯
  • vue2与vue3版本参数、事件使用方法一致,升级成本基本为0
  • 组件基本覆盖了高德JSAPI2.0和可视化loca2.0的所有功能
  • vue3版本支持常用IDE提示
  • vue3版本支持tree-shaking

安装方法

npm安装

npm install @vuemap/vue-amap@next --save


import App from './App.vue'
import VueAMap, {initAMapApiLoader} from '@vuemap/vue-amap';
import '@vuemap/vue-amap/dist/style.css'
initAMapApiLoader({
    key: 'YOUR_KEY'
})

createApp(App)
    .use(Element)
    .mount('#app')

CDN安装

<script src="https://unpkg.com/@vuemap/vue-amap@next/dist/index.js"></script>
<script src="https://unpkg.com/@vuemap/vue-amap@next/dist/style.css"></script>

window.VueAmap.initAMapApiLoader({
  key: 'YOUR_KEY',
});

使用示例

加载地图

<template>
  <div class="map-page-container">
    <el-amap
      :center="center"
      :zoom="zoom"
      @init="init"
    />
  </div>
  <div class="toolbar">
    <button @click="add()">
      添加标号
    </button>
  </div>
</template>

<script lang="ts">
import {defineComponent} from "vue";

export default defineComponent({
  data() {
    return {
      zoom: 12,
      center: [121.59996, 31.197646],
      map: null
    };
  },

  methods: {
    init(map) {
      const marker = new AMap.Marker({
        position: [121.59996, 31.197646]
      });
      map.add(marker);
      this.map = map;
      console.log('map init: ', map)
    },
    add() {
      const marker = new AMap.Marker({
        position: [121.59996, 31.177646]
      });
      this.map.add(marker);
    }
  }
})
</script>

<style>
</style>

添加交通图层

<template>
  <div class="map-page-container">
    <el-amap :center="center" :zoom="zoom">
      <el-amap-layer-traffic :visible="visible"></el-amap-layer-traffic>
    </el-amap>
  </div>
  <div class="toolbar">
    <button @click="switchVisible()">{{visible? '隐藏' : '显示'}}</button>
  </div>
</template>

<style>
</style>

<script lang="ts">
import {defineComponent} from "vue";

export default defineComponent({
  data() {
    return {
      zoom: 12,
      center: [121.59996, 31.197646],
      visible: true
    };
  },

  methods: {
    switchVisible() {
      this.visible = !this.visible;
    },
  }
});
</script>

添加标号

<template>
  <div class="map-page-container">
    <el-amap
      :show-label="false"
      :center="center"
      :zoom="zoom"
      @click="clickMap"
      @init="initMap"
    >
      <el-amap-marker
        :position="componentMarker.position"
        :visible="componentMarker.visible"
        :draggable="componentMarker.draggable"
        @init="markerInit"
        @click="clickMarker"
      >
        <div style="padding: 5px 10px;white-space: nowrap;background: blue;color: #fff;">
          测试content
        </div>
      </el-amap-marker>
      <el-amap-marker
        :position="componentMarker2.position"
        :content="componentMarker2.content"
      />
      <el-amap-marker
        v-for="(marker, index) in markers"
        :key="index"
        :position="marker.position"
        @click="(e) => {clickArrayMarker(marker, e)}"
      />
    </el-amap>
  </div>
  <div class="control-container">
    <button @click="changePosition">
      更换位置
    </button>
    <button @click="toggleVisible">
      {{ componentMarker.visible ? '隐藏标记' : '显示标记' }}
    </button>
    <button @click="changeDraggable">
      {{ componentMarker.draggable ? '禁止标记移动' : '允许标记移动' }}
    </button>
  </div>
</template>

<script lang="ts">
import {defineComponent} from "vue";

export default defineComponent({
  name: "Map",
  data(){
    return {
      center: [121.5273285, 31.21515044],
      zoom: 16,
      markers: [
        {
          position: [121.5273285, 31.21515044],
          id: 1
        }
      ],
      componentMarker: {
        position: [121.5273285, 31.21315058],
        visible: true,
        draggable: false
      },
      componentMarker2: {
        position: [121.5283285, 31.21315058],
        content: 'hello world'
      },
    }
  },
  methods: {
    clickMap(e){
      console.log('click map: ', e);
    },
    initMap(map){
      console.log('init map: ', map);
    },
    changeCenter(){
      const lng = this.center[0]+0.01;
      const lat = this.center[1]+0.01;
      this.center = [lng, lat];
    },
    changePosition() {
      const position = this.componentMarker.position;
      this.componentMarker.position = [position[0] + 0.002, position[1] - 0.002];
    },
    changeDraggable() {
      this.componentMarker.draggable = !this.componentMarker.draggable;
    },
    toggleVisible() {
      this.componentMarker.visible = !this.componentMarker.visible;
    },
    markerInit(e){
      console.log('marker init: ', e);
    },
    clickMarker(){
      alert('点击了标号')
    },
    clickArrayMarker(marker){
      alert(`点击了标号,标号ID: ${marker.id}`)
    }
  }
})
</script>

<style scoped>
</style>

Loca的Icon图层

<template>
  <div class="map-page-container">
    <el-amap
      view-mode="3D"
      :pitch="pitch"
      :show-label="false"
      :center="center"
      :zoom="zoom"
      @click="clickMap"
      @init="initMap"
    >
      <el-amap-loca>
        <el-amap-loca-icon
          :visible="visible"
          :source-data="sourceData"
          :layer-style="layerStyle"
        />
      </el-amap-loca>
    </el-amap>
  </div>
  <div class="toolbar">
    <button @click="changeVisible">
      {{ visible ? '隐藏' : '显示' }}
    </button>
  </div>
</template>

<script lang="ts">
import {defineComponent} from "vue";


export default defineComponent({
  name: "Map",
  data() {
    const trafficIcons = {
      1: 'https://a.amap.com/Loca/static/loca-v2/demos/images/traffic-control.png',
      2: 'https://a.amap.com/Loca/static/loca-v2/demos/images/jam.png',
      3: 'https://a.amap.com/Loca/static/loca-v2/demos/images/construction.png',
      4: 'https://a.amap.com/Loca/static/loca-v2/demos/images/close.png',
      5: 'https://a.amap.com/Loca/static/loca-v2/demos/images/fog.png',
      0: 'https://a.amap.com/Loca/static/loca-v2/demos/images/accident.png',
    };
    return {
      center: [105.601, 35.32],
      zoom: 4.8,
      pitch: 55,
      visible: true,
      sourceData: {},
      layerStyle: {
        unit: 'px',
        icon: (index, feature) => {
          const data = feature.properties.rawData;
          const url = trafficIcons[data.type % Object.keys(trafficIcons).length];
          return url;
        },
        iconSize: [40,40],
        rotation: 0,
      }
    }
  },
  methods: {
    clickMap(e) {
      console.log('click map: ', e);
    },
    initMap(map) {
      console.log('init map: ', map);
      this.createData();
    },
    changeVisible() {
      this.visible = !this.visible;
    },
    createData(){
      fetch('/json/events.json').then(response => response.json()).then(events => {
        const _events = events[0].events;
        const list = _events.map(e => {
          const ll = e.lngLat.split(',');
          const arr = [parseFloat(ll[0]), parseFloat(ll[1])]
          return {
            "type": "Feature",
            "properties": {
              rawData: e
            },
            "geometry": {
              "type": "Point",
              "coordinates": arr
            }
          }
        })

        this.sourceData = Object.freeze({
          "type": "FeatureCollection",
          "features": list,
        });
      })
    },
  }
})
</script>

<style scoped>
</style>

展开阅读全文
加载中

作者的其它热门文章

打赏
0
0 收藏
分享
打赏
5 评论
0 收藏
0
分享
返回顶部
顶部