123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- <template>
- <div class="search-layout">
- <el-input v-model="keyword" placeholder="输入名称搜索" style="width: 350px" clearable>
- <template #append>
- <el-button :icon="Search" />
- </template>
- </el-input>
- <div class="search-result" v-show="keyword" ref="resultEl"></div>
- </div>
- <div class="def-select-map" ref="mapEl"></div>
- <div class="def-map-info" v-if="info">
- <p><span>经度</span>{{ info.lat }}</p>
- <p><span>维度</span>{{ info.lng }}</p>
- <p><span>缩放级别</span>{{ info.zoom }}</p>
- </div>
- </template>
- <script setup lang="ts">
- import AMapLoader from "@amap/amap-jsapi-loader";
- import { Search } from "@element-plus/icons-vue";
- import { ref, watchEffect } from "vue";
- import { QuiskExpose } from "@/helper/mount";
- import { debounce } from "@/util";
- export type MapImage = { blob: Blob | null };
- type MapInfo = { lat: number; lng: number; zoom: number };
- const keyword = ref("");
- const info = ref<MapInfo>();
- const mapEl = ref<HTMLDivElement>();
- const resultEl = ref<HTMLDivElement>();
- const searchAMap = ref<any>();
- watchEffect(async (onCleanup) => {
- if (!mapEl.value || !resultEl.value) {
- return;
- }
- const AMap = await AMapLoader.load({
- plugins: ["AMap.PlaceSearch"],
- key: "e661b00bdf2c44cccf71ef6070ef41b8",
- version: "2.0",
- });
- const map = new AMap.Map(mapEl.value, {
- WebGLParams: {
- preserveDrawingBuffer: true,
- },
- resizeEnable: true,
- });
- const placeSearch = new AMap.PlaceSearch({
- pageSize: 5,
- pageIndex: 1,
- map: map,
- panel: resultEl.value,
- autoFitView: true,
- });
- const getMapInfo = (): MapInfo => {
- var zoom = map.getZoom(); //获取当前地图级别
- var center = map.getCenter();
- return {
- zoom,
- lat: center.lat,
- lng: center.lng,
- };
- };
- //绑定地图移动与缩放事件
- map.on("moveend", () => (info.value = getMapInfo()));
- map.on("zoomend", () => (info.value = getMapInfo()));
- searchAMap.value = placeSearch;
- onCleanup(() => {
- searchAMap.value = null;
- map.destroy();
- });
- });
- const search = debounce((keyword: string) => {
- searchAMap.value.search(keyword);
- }, 1000);
- watchEffect(() => {
- searchAMap.value && search(keyword.value);
- });
- defineExpose<QuiskExpose>({
- submit() {
- return new Promise<MapImage>((resolve) => {
- if (mapEl.value) {
- const canvas = mapEl.value.querySelector("canvas") as HTMLCanvasElement;
- canvas.toBlob((blob) => resolve({ blob }));
- } else {
- resolve({ blob: null });
- }
- });
- },
- });
- </script>
- <style lang="scss" scoped>
- .search-layout {
- display: inline-block;
- position: relative;
- margin-bottom: 15px;
- z-index: 2;
- }
- .search-result {
- position: absolute;
- left: 0;
- right: 0;
- z-index: 1;
- overflow: hidden;
- &.show {
- max-height: 450px;
- overflow-y: auto;
- }
- }
- .def-map-info {
- margin-top: 10px;
- p {
- font-size: 14px;
- color: rgba(0, 0, 0, 0.85);
- display: inline;
- &:not(:last-child)::after {
- content: ",";
- margin-right: 6px;
- }
- }
- span::after {
- content: ":";
- }
- }
- .def-select-map {
- width: 540px;
- height: 390px;
- z-index: 1;
- }
- </style>
|