Skip to content
目录

Vue2中mapbox自定义弹窗

  • 自定义弹窗一般封装为组件,这里就不展示详细代码了

  • 弹窗一般伴随点击事件出现,所以也要监听地图点击事件

js
import mapboxgl from 'mapbox-gl'
import mapBoxBase from '@/mixins/mapBoxBase'
import mapPopup from './components/mapPopup.vue'
import Vue from 'vue'
import gcoord from 'gcoord'

 // 在data中申明地图弹窗变量
 mapPopup: null,

  mounted() {
    this.getMap()
    // 监听点击地图
    this.map.on('click', this.onMapClickMark)
  },

  methods: {
    // 地图标点并弹窗
    // isAddMap 是否需要重新添加点
    markerAndPopup(itemVal, isAddMap = true) {
      const transitionResult = gcoord.transform([itemVal.longitude, itemVal.latitude], gcoord.BD09, gcoord.WGS84)
      if (this.mapPopup) {
        this.mapPopup.remove()
      }
      const layerMqMarker = this.map.getLayer(`realTimeMap-MqMarker-${itemVal.id}`)
      if (!layerMqMarker && isAddMap && !this.markerAll) {
        const geoJSON = this.toGeoJSON({ lng: transitionResult[0], lat: transitionResult[1] }, itemVal.id)
        this.addMarkerLayer(
          'realTimeMap-Marker-list',
          geoJSON,
          this.markerImageUrl
        )
      }
      // 挂载弹窗
      const p = Vue.extend(mapPopup)
      // eslint-disable-next-line new-cap
      const vm = new p({
        propsData: {
          value: itemVal
        }
      })
      vm.$mount()
      this.mapPopup = new mapboxgl.Popup({ closeButton: true, offset: [-110, -15], closeOnClick: false, anchor: 'bottom' })
        .setLngLat([Number(transitionResult[0]), Number(transitionResult[1])])
        .setDOMContent(vm.$el)
        .addTo(this.map)
        // 飞行
      this.map.flyTo({
        center: [Number(transitionResult[0]), Number(transitionResult[1])],
        zoom: 12,
        bearing: 0
      })
    },

    // 点击地图
    onMapClickMark(e) {
      const features = this.map.queryRenderedFeatures(e.point)
      // 只能点击到Marker
      if (features.length && features[0].layer.id.includes('Marker')) {
        this.getRecordDetail(features[0].properties.id)
      }
    },

    // 获取详情
    getRecordDetail(id, isAddMap = false) {
      this.mapLoading = true
      return this.$api.get(`/api/xxxx/${id}`).then(res => {
        this.mapLoading = false
        if (res.data.id) {
          this.markerAndPopup(res.data, isAddMap)
          return res
        } else {
          this.$notify.error({
            title: '获取详情失败',
            message: res.message || ''
          })
        }
      })
    },
  }

Released under the MIT License.