mapbox官方示例:http://www.mapbox.cn/mapbox-gl-js/example/set-popup/
在这里插入图片描述

方法一:字符串拼接弹框内容:(弹框内容样式少的情况下)
效果图:
在这里插入图片描述

核心代码:

var popup = new mapboxgl.Popup({ offset: 25 }).setHTML(`<div class="makerTop"><h2 class="markerHear" > 综合办一处 </h2></div>'
                            '<div class="markerBody" ><p>设在单位:兴安盟乌兰浩特市市政府</p>' 
                            '<p>详细地址:兴安盟乌兰浩特市</p>' 
                            '<p>负&ensp;责&ensp;人:杨子林</p>'
                            '<p>军&emsp;&emsp;电:0311-2564558'</p></div>`)
new mapboxgl.Marker(el)
  .setLngLat(coordinate)
  .setPopup(popup) // sets a popup on this marker
  .addTo(this.mapInst)

完整实现:

<template>
  <div style="height: 100%; width: 100%; text-align: left">
    <div ref="basicMapbox" :style="mapSize" class="mapClass"></div>
  </div>
</template>
<script>
import mapboxgl from 'mapbox-gl'

export default {
  props: {
    mapWidth: {
      type: String,
    },
    mapHeight: {
      type: String,
    },
    mapData: {
      type: Array,
      required: false,
    },
  },
  components: {},
  data() {
    return {
      mapInst: '',
      // 组件加载后隐藏
      showInfoWindow: false,
      popupTemp: null,
      lengeData: {
        lev1_show: true,
        lev2_show: true,
      },
      visible: false,
      mapDataCopy: JSON.parse(JSON.stringify(this.mapData)),
      currentMarkers: [], //标记点集合
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      mapboxgl.accessToken = 'pk.eyJ1IjoibWVpaW4xxxxxxxxxxxxxxxxxxxxxxqbWtlemR5MGt4MTJ4bjBxcjNmcng5NCJ9.GRpGEmZhxJ58EkNW6Ta_AQ'
      this.mapInst = new mapboxgl.Map({
        container: this.$refs.basicMapbox,
        style: 'https://xxxxxxxxx.cn/vector-styles/mapbox/mapbox-light.json',
        center: [113.34411, 23.141], // 地图初始化时的地理中心点
        zoom: 8,
      })
      this.loadPoint()
    },
    // 加载点位
    loadPoint() {
      console
      this.mapDataCopy.forEach((item) => {
        let coordinate = [Number(item.longitude), Number(item.latitude)]
        let el = document.createElement('div')
        el.id = 'markerId'
        if (item.status === 1) {
          el.style.backgroundColor = '#3AB236'
          el.style.width = 14 + 'px'
          el.style.height = 14 + 'px'
          el.style.borderRadius = '50%'
        } else if (item.status === 2) {
          el.style.backgroundColor = '#EC4646'
          el.style.width = 14 + 'px'
          el.style.height = 14 + 'px'
          el.style.borderRadius = '50%'
        }

        let marker = new mapboxgl.Marker(el).setLngLat(coordinate).setOffset([0, -19]).addTo(this.mapInst) // 将标记添加到地图上
        this.currentMarkers.push(marker)
		
		// 添加弹窗
        var popup = new mapboxgl.Popup({ offset: 25 }).setHTML(`<div class="makerTop"><h2 class="markerHear" > 综合办一处 </h2></div>'
                            '<div class="markerBody" ><p>设在单位:兴安盟乌兰浩特市市政府</p>' 
                            '<p>详细地址:兴安盟乌兰浩特市</p>' 
                            '<p>负&ensp;责&ensp;人:杨子林</p>'
                            '<p>军&emsp;&emsp;电:0311-2564558'</p></div>`)
        new mapboxgl.Marker(el)
          .setLngLat(coordinate)
          .setPopup(popup) // sets a popup on this marker
          .addTo(this.mapInst)       
      })
    },
  },
  computed: {
    mapSize() {
      let styleObj = {
        width: this.mapWidth,
        height: this.mapHeight,
      }
      return styleObj
    },
  },
  watch: {
    mapData: function (val) {
      if (val) {
        this.mapDataCopy = JSON.parse(JSON.stringify(this.mapData))
        this.init()
      }
    },
  },
}
</script>

方法二:将弹框内容抽出组件:(弹框内容样式多、复杂的情况下)
参考:mapbox popup挂载自定义组件:https://www.jianshu.com/p/9e68e081ab3b

效果图:
在这里插入图片描述
实现:
核心代码:

// 添加弹窗
        const popDetail = Vue.extend(InfoWindow)
        let vm = new popDetail({
          propsData: {
            detailId: 121,
          },
        })
        vm.$mount() //挂载
        this.popupTemp = vm.$el
        var popup = new mapboxgl.Popup({ offset: 25 }).setDOMContent(this.popupTemp)
        new mapboxgl.Marker(el)
          .setLngLat(coordinate)
          .setPopup(popup) // sets a popup on this marker
          .addTo(this.mapInst)

完整实现:

<template>
  <div style="height: 100%; width: 100%; text-align: left">
    <div ref="basicMapbox" :style="mapSize" class="mapClass"></div>

    <!-- 弹窗 -->
    <InfoWindow v-show="showInfoWindow" ref="infoWindow"></InfoWindow>
  </div>
</template>
<script>
import mapboxgl from 'mapbox-gl'
import InfoWindow from './myWindow'
import Vue from 'vue'

export default {
  props: {
    mapWidth: {
      type: String,
    },
    mapHeight: {
      type: String,
    },
    mapData: {
      type: Array,
      required: false,
    },
  },
  components: {
    InfoWindow,
  },
  data() {
    return {
      mapInst: '',
      // 组件加载后隐藏
      showInfoWindow: false,
      popupTemp: null,
      lengeData: {
        lev1_show: true,
        lev2_show: true,
      },
      visible: false,
      mapDataCopy: JSON.parse(JSON.stringify(this.mapData)),
      currentMarkers: [], //标记点集合
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    // 初始化
    init() {
      mapboxgl.accessToken = 'pk.eyJ1IjoibWVpaW4xMjM0NTYiLCJhIjoiY2tqbWtlemR5MGt4MTJ4bjBxcjNmcng5NCJ9.GRpGEmZhxJ58EkNW6Ta_AQ'
      this.mapInst = new mapboxgl.Map({
        container: this.$refs.basicMapbox,
        style: 'https://it.gdeei.cn/vector-styles/mapbox/mapbox-light.json',
        center: [113.34411, 23.141], // 地图初始化时的地理中心点
        zoom: 8,
      })
      this.loadPoint()
    },
    // 加载点位
    loadPoint() {
      console
      this.mapDataCopy.forEach((item) => {
        let coordinate = [Number(item.longitude), Number(item.latitude)]
        let el = document.createElement('div')
        el.id = 'markerId'
        if (item.status === 1) {
          el.style.backgroundColor = '#3AB236'
          el.style.width = 14 + 'px'
          el.style.height = 14 + 'px'
          el.style.borderRadius = '50%'
        } else if (item.status === 2) {
          el.style.backgroundColor = '#EC4646'
          el.style.width = 14 + 'px'
          el.style.height = 14 + 'px'
          el.style.borderRadius = '50%'
        }

        let marker = new mapboxgl.Marker(el).setLngLat(coordinate).setOffset([0, -19]).addTo(this.mapInst) // 将标记添加到地图上
        this.currentMarkers.push(marker)

        // 添加弹窗
        const popDetail = Vue.extend(InfoWindow)
        let vm = new popDetail({
          propsData: {
            detailId: 121,
          },
        })
        vm.$mount() //挂载
        this.popupTemp = vm.$el
        var popup = new mapboxgl.Popup({ offset: 25 }).setDOMContent(this.popupTemp)
        new mapboxgl.Marker(el)
          .setLngLat(coordinate)
          .setPopup(popup) // sets a popup on this marker
          .addTo(this.mapInst)
      })
    },
  },
  computed: {
    mapSize() {
      let styleObj = {
        width: this.mapWidth,
        height: this.mapHeight,
      }
      return styleObj
    },
    // 颜色
    back_Color: function () {
      return function (val) {
        switch (val) {
          case 1:
            return '#3AB236'
          case 2:
            return '#EC4646'
        }
      }
    },
  },
  watch: {
    mapData: function (val) {
      if (val) {
        this.mapDataCopy = JSON.parse(JSON.stringify(this.mapData))
        this.init()
      }
    },
  },
}
</script>
<style lang="scss" scoped>
.coordinates {
  background: rgba(0, 0, 0, 0.5);
  color: #fff;
  position: absolute;
  bottom: 40px;
  left: 10px;
  padding: 5px 10px;
  margin: 0;
  font-size: 11px;
  line-height: 18px;
  border-radius: 3px;
  display: none;
}
.mapClass /deep/ .mapboxgl-popup-content {
  width: 324px;
  height: 273px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
  padding: 15px;
}
.mapClass /deep/ .mapboxgl-popup-close-button {
  cursor: pointer;
  color: #333333;
  font-size: 24px;
  font-weight: bold;
  margin: 5px 10px;
  border: none;
  &:hover {
    color: #5393e7;
    background: unset;
  }
  :focus {
    outline: none;
  }
}

// 正常/异常的popover
.lenged_new {
  position: absolute;
  bottom: 40px !important;
  right: 60px;
}

.lenContent {
  width: 78px;
  height: 78px;
  background: #ffffff;
  border: 1px solid #e6e6e6;
  box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.1);
  border-radius: 4px;

  display: flex;
  flex-direction: column;
  justify-content: center;
  margin: 0 auto;

  div {
    opacity: 0.5;
  }
  div.active_air {
    opacity: 1;
  }

  .len_item {
    display: flex;
    justify-content: center;
    font-size: 14px;
    line-height: 14px;
    height: 14px;
    cursor: pointer;

    .len_icon {
      width: 10px;
      height: 10px;
      border-radius: 50%;
      margin-right: 5px;
    }
    .red {
      background: #ec4646;
    }
    .green {
      background: #3ab236;
    }
  }
}
</style>

样式组件 myWindow:

<template>
  <div class="box-card">
    <div class="content_box">这里是样式</div>
  </div>
</template>
<script>
export default {
  props: {
    infoWindow: {
      type: Object,
      default: () => {},
    },
    detailId: {
      type: Number,
      required: false,
    },
  },
  data() {
    return {}
  },
  methods: {},
}
</script>
<style lang="scss" scoped>
.content_box {
  width: 100px;
  height: 100px;
  background: skyblue;
}
</style>
Logo

前往低代码交流专区

更多推荐