当前位置: 首页 > news >正文

Vue3地图选点组件

Vue3地图选点组件
在这里插入图片描述

<template><div style="width: 100%; height: 500px"><div class="search-container"><el-autocompletev-model="suggestionKeyWord"class="search-container__input"clearable:fetch-suggestions="searchSuggestions"placeholder="输入关键字搜索"@select="onSuggestionChoose"><template #default="{ item }"><div class="value">{{ item.name }}</div><span class="link">{{ item.address }}</span></template></el-autocomplete><el-button type="primary" class="search-container__button" @click="doneMap"> 确定 </el-button></div><div class="map-body"><div id="container" class="map-body__left"></div><img :class="iconClass" :src="markerSrc" alt="" /><!-- poi數據 --><div class="map-body__right ele-map-picker-poi-list"><divv-for="(poi, index) in poiData":key="index":class="['ele-map-picker-poi-item',{ 'ele-map-picker-poi-item-active': index === chooseIndex },]"@click="choose(index)"><el-icon class="ele-map-picker-poi-item-icon el-icon-location-outline"><Location/></el-icon><!-- <icon-ep-location class="ele-map-picker-poi-item-icon el-icon-location-outline" /> --><div class="ele-map-picker-poi-item-title">{{ poi.name }}</div><div v-if="poi.address" class="ele-map-picker-poi-item-address">{{ poi.address }}</div><el-icon v-if="index === chooseIndex" class="ele-map-picker-poi-item-check"><Check/></el-icon><!-- <icon-park-check-smallv-if="index === chooseIndex"class="ele-map-picker-poi-item-check"/> --></div></div></div></div>
</template><script lang="ts" setup>import { onMounted } from 'vue';import AMapLoader from '@amap/amap-jsapi-loader';import markerSrc from '@/assets/images/location.png';import type { Poi } from './type';// const props = defineProps({});const emit = defineEmits(['done-map']);// 中心点位置let location: any = reactive([116.4074, 39.9042]);// 地图缩放比例const chooseZoom = 15;// 搜索关键字const suggestionKeyWord = ref('');// 搜索建议列表let suggestionData = reactive([]);// 地图实例let map: any;// 输入建议实例let autoComplete = reactive({});// 选中的建议let chooseSuggestion = reactive<any>({});// 地图中心标记点let centerMarker = reactive({});// poi检索实例let placeSearch = reactive({});// poi检索的数据const poiData = ref<Poi[]>([]);// 选中的数据const chooseIndex = ref<any>(null);// 是否是点击poi列表移动地图let isSelMove = false;// 图标是否显示跳动动画const showIconAnim = ref(false);const iconClass = computed(() => {return ['ele-map-picker-main-icon', { 'ele-map-picker-anim-bounce': showIconAnim.value }];});/*** @description: 初始化地图* @param {*} local* @return {*}*/const initMap = (local: any) => {AMapLoader.load({key: 'xxxxxxxxxxxxx', // 申请好的Web端开发者Key,首次调用 load 时必填version: '2.0', // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15plugins: ['AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.AutoComplete'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等}).then((AMap) => {map = new AMap.Map('container', {zoom: chooseZoom,center: location,});// 输入建议实例autoComplete = new AMap.AutoComplete({city: '全国',});// marker实例centerMarker = new AMap.Marker({icon: new AMap.Icon({image: markerSrc,size: new AMap.Size(26, 36.5),imageSize: new AMap.Size(26, 36.5),}),offset: new AMap.Pixel(-13, -36.5),});addMarker(location[0], location[1]);// 获取poi检索实例placeSearch = new AMap.PlaceSearch({type: '', // poi检索兴趣点类别pageSize: 30, // poi检索每页数量pageIndex: 1,extensions: 'all',});// 地图加载完成事件map.on('complete', () => {chooseIndex.value = null;const center = map.getCenter();searchNearBy(center.lat, center.lng, true);});// 地图移动结束事件map.on('moveend', () => {const center = map.getCenter();addMarker(center.lng, center.lat);if (isSelMove) {// poi列表点击的移动isSelMove = false;} else {// 拖动或搜索建议的移动showIconAnim.value = false;nextTick(() => {setTimeout(() => {showIconAnim.value = true;}, 0);});searchNearBy(center.lat, center.lng);}});});};/*** @description: poi检索* @param {*} lat* @param {*} lng* @param {*} force* @return {*}*/const searchNearBy = (lat: any, lng: any) => {if (!placeSearch) {return;}// this.poiLoading = true;placeSearch.searchNearBy('', [lng, lat], 1000, (status: any, result: any) => {// this.poiLoading = false;if (status === 'complete') {const data = result.poiList.pois.filter((p: any) => p.location !== undefined);if (chooseSuggestion) {// 如果选中的搜索建议不在poi列表中则添加if (data.length === 0 || data[0].name !== chooseSuggestion.name) {data.unshift({ ...chooseSuggestion });}chooseSuggestion = null;} else {chooseIndex.value = null;}poiData.value = data;// v3.17 标准地址库-地址拼接省市区poiData.value.forEach((item) => {item.pname = item.pname || '';item.cityname = item.cityname || '';item.adname = item.adname || '';item.address = item.address || '';item.address = `${item.pname}${item.cityname}${item.adname}${item.address}`;});}});};/*** @description: poi列表选中* @param {*} index* @return {*}*/const choose = (index: number) => {chooseIndex.value = index;isSelMove = true;// this.showIconAnim = false;// nextTick(() => {//     setTimeout(() => {//         this.showIconAnim = true;//     }, 0);// });const point = poiData.value[index].location;map.setZoomAndCenter(chooseZoom, [point.lng, point.lat]);};/*** @description: 添加marker* @param {*} lng* @param {*} lat* @return {*}*/const addMarker = (lng: string, lat: string) => {// centerMarker.setMap(map);centerMarker.setPosition([lng, lat]);map.add(centerMarker);};/*** @description: 获取搜索数据* @param {*} keywords* @param {*} callback* @return {*}*/const searchSuggestions = (keywords: string, callback: any) => {if (!keywords) {return callback(suggestionData);}autoComplete.search(keywords, (status: any, result: any) => {if (status === 'complete') {suggestionData = result.tips.filter((item) => item.location);suggestionData.forEach((item: any) => {item.address = item.address || '';item.district = item.district || '';item.address = `${item.district}${item.address}`;});callback(suggestionData);}});};/*** @description: 点击选择* @param {*} item* @return {*}*/const onSuggestionChoose = (item: any) => {suggestionKeyWord.value = item.name;chooseSuggestion = item;chooseIndex.value = 0;const point = item.location;if (point) {map.setZoomAndCenter(chooseZoom, [point.lng, point.lat]);addMarker(point.lng, point.lat);}};/*** @description: 确定* @return {*}*/const doneMap = () => {// 地图中心点// const center = { ...map.getCenter() };// getByLatLng({ lat: center.lat, lng: center.lng }).then((res) => {//   // console.log('接口获取的值', res);//   if (res.result) {//     location = {//       country: res.result?.country?.i18nName,//       province: res.result?.province?.i18nName || '',//       city: res.result?.city?.i18nName,//       district: res.result?.district?.i18nName,//       address: res.result.raw?.formattedAddress,//       lat: center.lat,//       lng: center.lng,//     };//   }//   // 选中则取高德地图返回的address//   if (chooseIndex.value || chooseIndex.value === 0) {//     location.address = poiData.value[chooseIndex.value].address || '';//   }//   suggestionKeyWord.value = '';//   emit('done-map', location);// });// TODO 由于数据规范性,需获取经纬度后重新请求三级地址if (chooseIndex.value || chooseIndex.value === 0) {location.address = poiData.value[chooseIndex.value].address || '';}console.log('选中的地址', location);suggestionKeyWord.value = '';emit('done-map', location);};onMounted(() => {setTimeout(() => {initMap(location);}, 200);});
</script><style scoped lang="scss">#container {margin: 0;padding: 0;width: 100%;height: calc(100% - 50px);}.search-container {display: flex;justify-content: space-between;margin-bottom: 10px;:deep(.el-autocomplete) {width: 80%;}}.map-body {display: flex;height: 450px;&__left {width: 70% !important;height: 100% !important;}&__right {flex: 1;}}/* 地图图标跳动动画 */.ele-map-picker-anim-bounce {animation: elePickerAnimBounce 500ms;animation-direction: alternate;}@keyframes elePickerAnimBounce {0%,60%,75%,90%,to {transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);}0%,to {transform: translate3d(0, 0, 0);}25% {transform: translate3d(0, -10px, 0);}50% {transform: translate3d(0, -20px, 0);}75% {transform: translate3d(0, -10px, 0);}}.ele-map-picker-main-icon {width: 26px;position: absolute;left: 50%;bottom: 50%;margin-left: -13px;}/* poi列表 */.ele-map-picker-poi-list {overflow: auto;width: 300px;}.ele-map-picker-poi-item {position: relative;padding: 8px 30px 8px 44px;border-bottom: 1px solid hsl(0deg 0% 60% / 15%);cursor: pointer;}.ele-map-picker-poi-item:hover {background-color: hsl(0deg 0% 60% / 5%);}.ele-map-picker-poi-item-icon {position: absolute;top: 50%;left: 14px;transform: translateY(-50%);font-size: 20px;opacity: 0.4;}.ele-map-picker-poi-item-title {font-size: 14px;}.ele-map-picker-poi-item-address {margin-top: 2px;font-size: 12px;opacity: 0.6;}.ele-map-picker-poi-item .ele-map-picker-poi-item-check {position: absolute;top: 50%;right: 7px;display: none;font-size: 16px;color: #3b74ff;transform: translateY(-50%);}.ele-map-picker-poi-item-active .ele-map-picker-poi-item-check {display: block;}
</style>
<style lang="scss">.map-body {.amap-icon {display: none;}}
</style>
http://www.lryc.cn/news/273392.html

相关文章:

  • JS之注册事件兼容性解决方案
  • C#中使用as关键字将对象转换为指定类型
  • 【Spring实战】21 Spring Data REST 常用功能详细介绍
  • 05-微服务-RabbitMQ-概述
  • jmeter参数化的三种方式
  • java基础之Java8新特性-Lambda
  • 入门使用mybatis-plus
  • ubuntu安装和配置ssh教程
  • 每天刷两道题——第六天
  • 时间序列平稳性相关检验方法
  • <leetcode修炼>双指针训练-移动零
  • Python初探:从零开始的编程奇妙之旅
  • 算法与数据结构之链表<一>(Java)
  • 目标检测COCO数据集与评价体系mAP
  • 2024最全面且有知识深度的web3开发工具、web3学习项目资源平台
  • Golang - defer关键字 深入剖析
  • 如何在Spring Boot中使用@Scheduled写定时任务判断数据量是否过大,过大则进行分表操作,多张表使用临时视图查询
  • 使用jieba库进行中文分词和去除停用词
  • C语言之分支与循环【附6个练习】
  • 使用通用MCU实现无人机飞行任务的快速二次开发
  • 什么是Selinux
  • 计算机网络知识点
  • Qt 连接 Mysql
  • HarmonyOS4.0系统性深入开发14AbilityStage组件容器
  • 客服系统接入FastGPT
  • Hi5 2.0 虚拟手与追踪器(Tracker)的位置修正
  • 广播及代码实现
  • QT应用篇 三、QML自定义显示SpinBox的加减按键图片及显示值效果
  • 2022年全国职业院校技能大赛网络安全竞赛试题1-10-B模块总结
  • 20231228在Firefly的AIO-3399J开发板的Android11的Firefly的AIO-3399J开发板的DTS配置单前置摄像头ov13850