index.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div
  3. v-loading="loading"
  4. element-loading-text="地图加载中..."
  5. class="map-box"
  6. :class="{ 'no-pointer': isDesign }"
  7. >
  8. <div
  9. :id="`map-${config.code}`"
  10. style="width: 100%; height: 100%;"
  11. />
  12. </div>
  13. </template>
  14. <script>
  15. import AMapLoader from '@amap/amap-jsapi-loader'
  16. export default {
  17. name: 'RemoteMap',
  18. props: {
  19. config: {
  20. type: Object,
  21. default: () => ({})
  22. }
  23. },
  24. data () {
  25. return {
  26. map: null,
  27. loading: false
  28. }
  29. },
  30. computed: {
  31. option () {
  32. return this.config.option
  33. },
  34. optionData () {
  35. return this.option.data
  36. },
  37. customize () {
  38. return this.option.customize
  39. },
  40. isDesign () {
  41. return (window?.BS_CONFIG?.routers?.designUrl || '/big-screen/design') === this.$route.path
  42. }
  43. },
  44. mounted () {
  45. this.initMap()
  46. },
  47. methods: {
  48. initMap () {
  49. this.loading = true
  50. AMapLoader.load({
  51. key: this.customize.mapKey || '1b0a1423b70bbcbc20c9c87327e5e94e', // 申请好的Web端开发者Key,首次调用 load 时必填
  52. version: '1.4.15', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
  53. plugins: [
  54. 'AMap.ToolBar',
  55. 'AMap.Scale',
  56. 'AMap.HawkEye',
  57. 'AMap.MapType',
  58. 'AMap.Geolocation'
  59. ]
  60. }).then(() => {
  61. // 创建地图
  62. // eslint-disable-next-line no-undef
  63. this.map = new AMap.Map(`map-${this.config.code}`, {
  64. resizeEnable: true, // 是否监控地图容器尺寸变化
  65. lang: this.customize.lang,
  66. mapStyle: `amap://styles/${this.customize.mapStyle}`,
  67. center: [this.customize.lng, this.customize.lat],
  68. features: this.customize.features,
  69. zoom: this.customize.zoom,
  70. viewMode: this.customize.viewMode,
  71. plugins: ['AMap.ToolBar', 'AMap.Scale', 'AMap.MapType', 'AMap.Geolocation']
  72. })
  73. this.loading = false
  74. // eslint-disable-next-line no-undef
  75. this.map.addControl(new AMap.ToolBar())
  76. // 在图面添加比例尺控件,展示地图在当前层级和纬度下的比例尺
  77. // eslint-disable-next-line no-undef
  78. this.map.addControl(new AMap.Scale())
  79. // 在图面添加类别切换控件,实现默认图层与卫星图、实施交通图层之间切换的控制
  80. // eslint-disable-next-line no-undef
  81. this.map.addControl(new AMap.MapType())
  82. // 在图面添加定位控件,用来获取和展示用户主机所在的经纬度位置
  83. // eslint-disable-next-line no-undef
  84. this.map.addControl(new AMap.Geolocation())
  85. let marker = null // 用于存储标记对象的变量
  86. if (this.customize.markerSpan) {
  87. // 创建自定义标记内容
  88. const markerContent = document.createElement('div')
  89. markerContent.style.position = 'absolute'
  90. markerContent.style.width = '25px'
  91. markerContent.style.height = '34px'
  92. // 创建标记图标
  93. const markerImg = document.createElement('img')
  94. markerImg.src = '//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-red.png'
  95. markerImg.style.width = '25px'
  96. markerImg.style.height = '34px'
  97. markerContent.appendChild(markerImg)
  98. // 创建标记文本
  99. const markerSpan = document.createElement('span')
  100. markerSpan.className = 'marker'
  101. markerSpan.innerHTML = this.customize.markerSpan
  102. markerContent.appendChild(markerSpan)
  103. // 删除之前的标记(如果存在)
  104. if (marker) {
  105. this.map.remove(marker)
  106. }
  107. // 创建自定义标记
  108. // eslint-disable-next-line no-undef
  109. marker = new AMap.Marker({
  110. position: [this.customize.markerLng, this.customize.markerLat],
  111. content: markerContent,
  112. // eslint-disable-next-line no-undef
  113. offset: new AMap.Pixel(0, 0) // 设置标记偏移,使其指向标记位置
  114. })
  115. // 将标记添加到地图中
  116. this.map.add(marker)
  117. // 动态修改标记的 right 位置
  118. const markerElement = marker.getContent()
  119. const markerTextElement = markerElement.querySelector('.marker')
  120. markerTextElement.style.right = 0 // 设置初始的 right 值
  121. if (markerTextElement) {
  122. setTimeout(() => {
  123. markerTextElement.style.right = `-${markerTextElement.clientWidth}px` // 设置新的 right 值
  124. }, 100)
  125. }
  126. }
  127. })
  128. }
  129. }
  130. }
  131. </script>
  132. <style scoped></style>
  133. <style lang="scss" scoped>
  134. .no-pointer {
  135. pointer-events: none;
  136. }
  137. .map-box {
  138. width: 100%;
  139. height: 100%;
  140. z-index: 999;
  141. ::v-deep .amap-marker-content img {
  142. width: 25px;
  143. height: 34px;
  144. }
  145. ::v-deep .marker {
  146. position: absolute;
  147. top: -20px;
  148. right: -118px;
  149. color: #fff;
  150. padding: 4px 10px;
  151. box-shadow: 1px 1px 1px rgba(10, 10, 10, .2);
  152. white-space: nowrap;
  153. font-size: 12px;
  154. font-family: "";
  155. background-color: #25A5F7;
  156. border-radius: 3px;
  157. }
  158. }
  159. </style>