index.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <script setup lang="ts">
  2. import type { MapPickerProps } from './props'
  3. import { mapPickerEmits } from './props'
  4. import Amap from './components/amap.vue'
  5. import BaiDu from './components/baidu.vue'
  6. const emits = defineEmits(mapPickerEmits)
  7. const props = withDefaults(defineProps<MapPickerProps>(), {
  8. type: 'amap',
  9. height: '460px',
  10. markerSrc: 'https://3gimg.qq.com/lightmap/components/locationPicker2/image/marker.png',
  11. mapStyle: 'amap://styles/normal',
  12. suggestionCity: '太原市',
  13. search: true,
  14. poi: true,
  15. poiRadius: 1000,
  16. center: [112.569129, 37.863392],
  17. zoom: 11,
  18. selectedZoom: 17,
  19. message: '请选择位置',
  20. okText: '确定',
  21. poiKeywords: ''
  22. })
  23. /* 处理选择完成事件 */
  24. const handleDone = (data: any) => {
  25. emits('done', data)
  26. updateModalValue(false)
  27. }
  28. const updateModalValue = (modelValue: boolean) => {
  29. emits('update:modelValue', modelValue)
  30. }
  31. </script>
  32. <template>
  33. <el-dialog
  34. :model-value="modelValue"
  35. width="800px"
  36. title="位置选择"
  37. class="map-picker-dialog"
  38. @update:modelValue="updateModalValue"
  39. >
  40. <template v-if="modelValue">
  41. <!-- 高德地图 -->
  42. <Amap v-if="type === 'amap'" v-bind="props" :style="{ height }" @done="handleDone" />
  43. <!-- 百度地图 -->
  44. <BaiDu v-else v-bind="props" :style="{ height }" @done="handleDone" />
  45. </template>
  46. </el-dialog>
  47. </template>
  48. <style lang="scss">
  49. .map-picker-dialog {
  50. padding: 0px;
  51. .el-dialog__header {
  52. padding: var(--el-dialog-padding-primary);
  53. }
  54. .el-dialog__body {
  55. padding: 0px !important;
  56. .map-container {
  57. width: 100%;
  58. display: flex;
  59. .map-main {
  60. position: relative;
  61. flex: 1;
  62. }
  63. .map-keywrod-input {
  64. position: absolute;
  65. left: 8px;
  66. top: 8px;
  67. width: 200px;
  68. }
  69. .map-poi-side {
  70. width: 260px;
  71. height: 100%;
  72. display: flex;
  73. flex-direction: column;
  74. .map-poi-list {
  75. flex: 1;
  76. overflow-y: auto;
  77. box-sizing: border-box;
  78. .map-poi-item {
  79. display: flex;
  80. align-items: center;
  81. border-bottom: 1px solid var(--el-border-color);
  82. padding: 5px 0px;
  83. cursor: pointer;
  84. .map-poi-desc {
  85. flex: 1;
  86. }
  87. .map-poi-icon {
  88. padding: 0px 5px;
  89. }
  90. .map-poi-icon-checked {
  91. width: 30px;
  92. padding-left: 2px;
  93. }
  94. .map-poi-title {
  95. color: #333;
  96. font-size: 14px;
  97. }
  98. .map-poi-address {
  99. font-size: 13px;
  100. }
  101. }
  102. }
  103. .map-poi-button {
  104. height: 40px;
  105. padding: 5px;
  106. box-sizing: border-box;
  107. }
  108. }
  109. .map-icon-plus,
  110. .map-main-marker {
  111. position: absolute;
  112. top: 50%;
  113. left: 50%;
  114. z-index: 9;
  115. }
  116. .map-icon-plus {
  117. transform: translate(-50%, -50%);
  118. }
  119. .map-main-marker {
  120. width: 26px;
  121. margin-top: -35px;
  122. margin-left: -13px;
  123. }
  124. /* 地图图标跳动动画 */
  125. .map-main-marker-bounce {
  126. animation: mapAnim 0.6s;
  127. }
  128. @keyframes mapAnim {
  129. from,
  130. to {
  131. transform: translateY(0);
  132. }
  133. 50% {
  134. transform: translateY(-20px);
  135. }
  136. }
  137. }
  138. }
  139. }
  140. </style>