index.vue 5.2 KB

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