Vue3地图选点组件

news/2024/11/30 18:29:15/

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.ppmy.cn/news/1290562.html

相关文章

对偶问题的基本性质

写于&#xff1a;2024年1月3日晚 修改于&#xff1a; 原规划与对偶规划 原规划对偶规划 max ⁡ z C T X s.t. { A X ≤ b , 其中 X ( m ∗ 1 ) X ≥ 0 \begin{aligned} & \max \mathrm{z}\mathbf{C}^T \mathbf{X} \\ & \text { s.t. }\left\{\begin{array}{l}\mat…

迅为RK3588开发板使用 FFMpeg 进行推流

Debian/Ubuntu 系统使用以下命令安装 FFMpeg &#xff0c;如下图所示&#xff1a; apt-get install ffmpeg 使用 ifconfig 查看开发板 ip 为 192.168.1.245 如下图所示&#xff1a; 使用 FFMpeg 推流一个 mp4 视频进行测试&#xff0c;作者将测试视频 test.mp4 放在了根目录下…

人工智能教程(四):概率论入门

目录 前言 TensorFlow 入门 SymPy 入门 概率论入门 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站 在本系列的 上一篇文章 中&#xff0c;我们进一步讨论了矩阵和线性代数&#…

c++IO库详细介绍

文章目录 前言c IO 类简介1. iostream库iostream 类标准IO对象 2. fstream库fstream 类 3. stringstream库stringstream 类 格式化和控制错误处理 IO对象无拷贝或赋值IO条件状态主要的状态标志检查流状态控制流状态示例 管理输出缓冲主要操作示例 文件输入输出使用文件流对象示…

Mysql的四大引擎,账号管理,数据库的建立

数据库存储引擎查看 Support字段说明 default的为默认引擎 YES表示可以使用 NO表示不能使用 命令 SHOW ENGINES 四大引擎 MEMORY 使用场景&#xff1a;由于易失性&#xff0c;可以用于存储在分析中产生的中间表 特点 所有的数据都保存在内存中&#xff0c;一旦服务器重启&…

修改 Ubuntu 的配置

目录 一、修改地址 1. 修改本机IP 二、修改网关 1. 查看网关地址 2. 设置默认网关 三、重启网络 1. 重启网络 2. 刷新网络 四、修改主机名 1. 查看主机名 2. 修改主机名 一、修改地址 1. 修改本机IP sudo ifconfig en…

Oracle清理审计和监听垃圾文件脚本

Oracle用户删除审计文件自动化脚本 $&#xff08;ORACLE&#xff09; vi oracle_auto_trace_del.sh#!/bin/bash #ORACLE cd /opt/oracle/app/oracle/admin/SID(数据库实例名)/adump find . -type f -name "*.aud" -mtime 10 |xargs rm -rf$&#xff08;ORACLE&#…

【数据结构初阶】二叉树(2)

二叉树顺序结构 1.二叉树的顺序结构及实现1.1二叉树的顺序结构 1.2 堆的概念及结构1.3 堆的实现1.3.1向上调整1.3.2向下调整1.3.3交换函数1.3.4打印1.3.5初始化1.3.6销毁1.3.7插入1.3.8删除1.3.9获得堆顶元素1.3.10判断是否为空1.3.6 堆的代码实现 1.3.2堆的创建1.3.3 建堆时间…