基于高德地图JS API实现Vue地图选点组件

基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能,同时可以进行回显

目录

  • 1 创建key和秘钥
    • 1.1 登录高德地图开放平台
    • 1.2 创建应用
    • 1.3 绑定服务创建秘钥
  • 2 使用组件前准备
    • 2.1 导入loader
    • 2.2 在对应的组件设置秘钥
    • 2.3 引入css样式
  • 3 功能实现
    • 3.1 初始化地图
    • 3.2 增加搜索功能
    • 3.3 暴露增加标记函数
  • 4 全部代码
  • 5 实现效果

1 创建key和秘钥

1.1 登录高德地图开放平台

打开开放平台地址

注册账号 或 申请账号

1.2 创建应用

在这里插入图片描述

1.3 绑定服务创建秘钥

在这里插入图片描述

在这里插入图片描述

2 使用组件前准备

2.1 导入loader

推荐pnpm

pnpm i @amap/amap-jsapi-loader -D

2.2 在对应的组件设置秘钥

<script type="text/javascript" lang="ts">
window._AMapSecurityConfig = {
  securityJsCode: "安全秘钥"
};
</script>

2.3 引入css样式

<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />

3 功能实现

3.1 初始化地图

<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";

let map = null;
let aMap = null;
onMounted(() => {
  AMapLoader.load({
    key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }).then(AMap => {
    // 第一参数是对应的div的id
    map = new AMap.Map("container", {
      // 设置地图容器id
      viewMode: "3D", // 是否为3D地图模式
      zoom: 11, // 初始化地图级别
      center: [116.397428, 39.90923] // 初始化地图中心点位置
    });
    aMap = AMap;
  });
});
onUnmounted(() => {
  map?.destroy();
});
</script>
<template>
  <div id="map-box">
    <div id="container" />
    
  </div>
</template>
<style scoped>
#map-box {
  width: 100%;
  height: 450px;
  position: relative;
}
#container {
  width: 100%;
  height: 100%;
}

#myPageTop {
  position: absolute;
  top: 5px;
  right: 10px;
  font-family: "Microsoft Yahei", Pinghei;
  font-size: 14px;
  background: none 0px 0px repeat scroll rgb(255, 255, 255);
  border-width: 1px;
  border-style: solid;
  border-color: rgb(204, 204, 204);
  border-image: initial;
  margin: 10px auto;
  padding: 6px;
}
#panel {
  background-color: white;
  max-height: 400px;
  overflow-y: auto;
}
</style>

3.2 增加搜索功能

function search() {
  const placeSearch = new aMap.PlaceSearch({
    pageSize: 10, // 单页显示结果条数
    pageIndex: 1, // 页码
    map: map, // 展现结果的地图实例
    panel: "panel", // 结果列表将在此容器中进行展示。
    autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
  });
  //关键字查询
  placeSearch.search(keyword.value);
  placeSearch.on("selectChanged", function (e) {
    const data = e.selected.data;
    const temp = {
      province: data.pname,
      provinceCode: data.pcode,
      city: data.cityname,
      cityCode: data.citycode,
      county: data.adname,
      countyCode: data.adcode,
      storeAddr: data.address,
      storeDetailAddr: data.pname + data.cityname + data.adname + data.address,
      longitude: `${data.location.lng}`,
      latitude: `${data.location.lat}`
    };
    // 回调父组件
    emit("change", temp);
  });
}
// 宏注册emit
const emit = defineEmits(["change"]);

const keyword = ref("");
<template>
  <div id="map-box">
    <div id="container" />
    <!-- 增加的部分 -->
    <div id="myPageTop">
      <el-input
        @keyup.enter="search"
        placeholder="请输入地址"
        v-model="keyword"
      >
        <template #prepend>
          <el-button :icon="Search" @click="search" />
        </template>
      </el-input>
      <div id="panel" />
    </div>
  </div>
</template>

3.3 暴露增加标记函数

let loaded = false; // 判断地图是否完成渲染
const record = []; // 记录地图未加载完成之前的添加标签记录
// 循环渲染之前记录的地址
function loadRecord() {
  record.forEach(item => {
    addMarker(item.longitude, item.latitude, item.content);
  });
}
function addMarker(longitude: number, latitude: number, content: string) {
  if (!loaded) {
    record.push({ longitude, latitude, content });
    return;
  }
  if (!longitude || !latitude) return;
  const marker = new aMap.Marker({
    position: [longitude, latitude],
    icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
    anchor: "bottom-center",
    offset: new aMap.Pixel(0, 0)
  });

  marker.setMap(map);
  marker.setTitle(content);
  // 设置label标签
  // label默认蓝框白底左上角显示,样式className为:amap-marker-label
  marker.setLabel({
    direction: "bottom",
    offset: new aMap.Pixel(0, 0), //设置文本标注偏移量
    content: `<div style='padding:1px 5px;'>${content}</div>` //设置文本标注内容
  });
  map.setZoomAndCenter(11, [longitude, latitude]); //同时设置地图层级与中心点
}
defineExpose({
  addMarker
});

4 全部代码

<link rel="stylesheet" href="https://cache.amap.com/lbs/static/main1119.css" />
<script type="text/javascript" lang="ts">
window._AMapSecurityConfig = {
  securityJsCode: "秘钥"
};
</script>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
import { Search } from "@element-plus/icons-vue";

let map = null;
let aMap = null;
let loaded = false;
const record = []; // 记录地图未加载完成之前的添加标签记录
onMounted(() => {
  AMapLoader.load({
    key: "key", // 申请好的Web端开发者Key,首次调用 load 时必填
    version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
    plugins: ["AMap.PlaceSearch", "AMap.AutoComplete"] // 需要使用的的插件列表,如比例尺'AMap.Scale'等
  }).then(AMap => {
    // 第一参数是对应的div的id
    map = new AMap.Map("container", {
      // 设置地图容器id
      viewMode: "3D", // 是否为3D地图模式
      zoom: 11, // 初始化地图级别
      center: [116.397428, 39.90923] // 初始化地图中心点位置
    });
    aMap = AMap;
    // 地图加载完成后会触发此回调函数
    loaded = true;
    loadRecord();
  });
});
onUnmounted(() => {
  map?.destroy();
});
// 循环渲染之前记录的地址
function loadRecord() {
  record.forEach(item => {
    addMarker(item.longitude, item.latitude, item.content);
  });
}
function addMarker(longitude: number, latitude: number, content: string) {
  if (!loaded) {
    record.push({ longitude, latitude, content });
    return;
  }
  if (!longitude || !latitude) {
  	console.error("缺少必要信息")
  	return;
  }
  const marker = new aMap.Marker({
    position: [longitude, latitude],
    icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
    anchor: "bottom-center",
    offset: new aMap.Pixel(0, 0)
  });

  marker.setMap(map);
  marker.setTitle(content);
  // 设置label标签
  // label默认蓝框白底左上角显示,样式className为:amap-marker-label
  marker.setLabel({
    direction: "bottom",
    offset: new aMap.Pixel(0, 0), //设置文本标注偏移量
    content: `<div style='padding:1px 5px;'>${content}</div>` //设置文本标注内容
  });
  map.setZoomAndCenter(11, [longitude, latitude]); //同时设置地图层级与中心点
}
defineExpose({
  addMarker
});
function search() {
  const placeSearch = new aMap.PlaceSearch({
    pageSize: 10, // 单页显示结果条数
    pageIndex: 1, // 页码
    map: map, // 展现结果的地图实例
    panel: "panel", // 结果列表将在此容器中进行展示。
    autoFitView: true // 是否自动调整地图视野使绘制的 Marker点都处于视口的可见范围
  });
  //关键字查询
  placeSearch.search(keyword.value);
  placeSearch.on("selectChanged", function (e) {
    const data = e.selected.data;
    const temp = {
      province: data.pname,
      provinceCode: data.pcode,
      city: data.cityname,
      cityCode: data.citycode,
      county: data.adname,
      countyCode: data.adcode,
      storeAddr: data.address,
      storeDetailAddr: data.pname + data.cityname + data.adname + data.address,
      longitude: `${data.location.lng}`,
      latitude: `${data.location.lat}`
    };
    // 回调父组件
    emit("change", temp);
  });
}
const emit = defineEmits(["change"]);

const keyword = ref("");
</script>

<template>
  <div id="map-box">
    <div id="container" />
    <!-- 增加的部分 -->
    <div id="myPageTop">
      <el-input
        @keyup.enter="search"
        placeholder="请输入地址"
        v-model="keyword"
      >
        <template #prepend>
          <el-button :icon="Search" @click="search" />
        </template>
      </el-input>
      <div id="panel" />
    </div>
  </div>
</template>

<style scoped>
#map-box {
  width: 100%;
  height: 450px;
  position: relative;
}
#container {
  width: 100%;
  height: 100%;
}

#myPageTop {
  position: absolute;
  top: 5px;
  right: 10px;
  font-family: "Microsoft Yahei", Pinghei;
  font-size: 14px;
  background: none 0px 0px repeat scroll rgb(255, 255, 255);
  border-width: 1px;
  border-style: solid;
  border-color: rgb(204, 204, 204);
  border-image: initial;
  margin: 10px auto;
  padding: 6px;
}
#panel {
  background-color: white;
  max-height: 400px;
  overflow-y: auto;
}
</style>

5 实现效果

回显效果,会自动设置到地图中心
在这里插入图片描述
选点效果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/461782.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

记录dockers中Ubuntu安装python3.11

参考&#xff1a; docker-ubuntu 安装python3.8,pip3_dockerfile ubuntu22 python3.8-CSDN博客

揭示数据在内存中存储的秘密!

** ** 悟已往之不谏&#xff0c;知来者犹可追 ** ** 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免费的赞哟~ 整数在内存中的存储 整数的表达方式有三种&#xff1a;原码、反码、补码。 三种表示方法均有符号位和数值位两部分…

Oracle数据库:使用 bash脚本 + 定时任务 自动备份数据

Oracle数据库&#xff1a;使用 bash脚本 定时任务 自动备份数据 1、前言2、为什么需要自动化备份&#xff1f;3、编写备份脚本4、备份脚本授权5、添加定时任务6、重启 crond / 检查 crond 服务状态7、备份文件检查 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收…

matlab 平面桁架有限元受力分析计算

1、内容简介 略 62-可以交流、咨询、答疑 平面桁架有限元受力分析计算 2、内容说明 略 3、仿真分析 略 4、参考论文 略

宿主环境

1. 什么是宿主环境 宿主环境&#xff08; host environment &#xff09;指的是程序运行所必须的依赖环境。例如&#xff1a; Android 系统和 iOS 系统是两个不同的宿主环境。安卓版的微信 App 是不能在 iOS 环境下运行的&#xff0c;所以&#xff0c; Android 是安卓软件的宿…

“import ... =“ 只能在 TypeScript 文件中使用

当你遇到这个问题很苦恼。 可以按照以下解决办法 使用ctrlshiftP 修改"javascript.validate.enable": false

php中 0 == ‘’(0等于任意字符串) 判断是否成立 返回true

php中不同类型变量之间比较大小 一、背景二、探究0是为什么&#xff1f;三、探究 0all是为什么&#xff1f;四、程序中如何判断0是否等于指定字符串 一、背景 最近在项目实际开发中&#xff0c;我需要判断前端传来的参数值是否等于一个字符串&#xff1b;然后发现当参数值是0时…

MATLAB学习笔记(二)PDE求解偏微分方程组

一、利用PDE求解偏微分方程组 初值为&#xff1a; 针对上述方程组&#xff0c;利用matlab自带工具箱和函数PDE进行求解。 以下是matlab中对工具箱中pdepe函数的解释。 二、matlab编程 在matlab中编程&#xff0c;利用PDE函数求解以上偏微分方程。 clc; clear; syms y global …

【蓝桥杯单片机】十三届省赛“重难点”解析(附源码)

【蓝桥杯单片机】十三届省赛“重难点”解析 一、题目难点解析二、易出错点提示三、完整代码链接 笔记包括&#xff1a;①题目难点解析、②易出错点提示、③完整代码链接 注&#xff1a;本文提供的所有代码都是使用第十四届竞赛包完成 ⭐----------系列文章链接----------⭐ 【蓝…

Java初阶数据结构二叉树实现+练习完整(工程文件后序会进行上传)

i1.二叉树的概念 1.二叉树的定义 &#xff08;1&#xff09;二叉树可以是一个节点的有限集合 &#xff08;2&#xff09;可以为空 &#xff08;3&#xff09;或者是由一个根节点加上两棵分别称为左子树和右子树的二叉树组成的 &#xff08;4&#xff09;二叉树的每一个节点…

力扣细节题:字符串中的最大奇数

奇数只要找到第一位是奇数的即可&#xff0c;不是找单个数字 //即从最低位开始&#xff0c;找到第一位为奇数的位 //然后之前的就是需要的数字char * largestOddNumber(char * num){int i strlen(num) - 1;while(i > 0){if((num[i] - 0) % 2 1)break;i--;}//先找到低位开…

电子科技大学链时代工作室招新题C语言部分---题号E

1. 题目 这道题大概的意思是说&#xff0c;一座城市中被埋了许多雷&#xff08;用一个只含0和1的字符串表示城市&#xff0c;1代表有雷&#xff0c;0代表无雷&#xff09;。 你作为一个排雷兵&#xff0c;需要花最少的钱引爆所有的雷来使城市中不再有雷&#xff08;太逆天了&a…

Java宝典-异常

目录 1. 异常的分类1.1 运行时异常1.2 编译时异常 2. 异常的抛出2.1 throw2.2 throws 3. 异常的捕获3.1 try-catch3.2 finally 4. 异常执行的过程5. 自定义异常 在Java中&#xff0c;异常(Exception)是指程序发生不正常的行为&#xff0c;异常其实就是一个一个的类。 1. 异常的…

c++刷题(自用)(问题合集)---(一直会更)

初始化列表易错点 #include <iostream> using namespace std;struct A {A() { std::cout << "A"; } }; struct B {B() { std::cout << "B"; } };class C { public:C() : a(), b(){std::cout << "C";}private:B b;A a; …

【AcWing】蓝桥杯集训每日一题Day5|归并排序|离散化|二分|逆序数对|505.火柴排队(C++)

火柴排队 505. 火柴排队 - AcWing题库难度&#xff1a;中等时/空限制&#xff1a;1s / 128MB总通过数&#xff1a;2058总尝试数&#xff1a;4484来源&#xff1a;NOIP2013提高组算法标签贪心离散化树状数组归并排序 题目内容 涵涵有两盒火柴&#xff0c;每盒装有 n 根火柴…

基于Pnpm + Turborepo + QianKun的微前端+Monorepo实践

基于Pnpm Turborepo QianKun的微前端Monorepo实践 背景 微前端一般都会涉及多个代码库&#xff0c;很多时候要一个一个代码库地去开发维护和运行&#xff0c;很不方便&#xff0c;这种时候引入Monorepo搭配微前端就能很好地解决这种问题&#xff0c;一个代码库就可以完成整…

AI赋能写作:AI大模型高效写作一本通

❤️作者主页&#xff1a;小虚竹 ❤️作者简介&#xff1a;大家好,我是小虚竹。2022年度博客之星评选TOP 10&#x1f3c6;&#xff0c;Java领域优质创作者&#x1f3c6;&#xff0c;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;掘金年度人气作…

文件包含例子

一、常见的文件包含函数 php中常见的文件包含函数有以下四种&#xff1a; include() require() include_once() require()_once() include与require基本是相同的&#xff0c;除了错误处理方面: include()&#xff0c;只生成警告&#xff08;E_WARNING&#xff09;&#x…

linux之source.list解析

众所周知&#xff0c;linux可以通过apt命令安装软件&#xff0c;那么apt又是从哪里获取软件包呢并安装呢&#xff1f;这里就绕不开一个文件source.list&#xff0c;该文件定义了软件源相关的信息。下面以实际例子&#xff0c;详细的介绍下这个文件。 文件作用 定义软件源的信…

MySQL-HMA 高可用故障切换

本章内容&#xff1a; 了解MySQL MHA搭建MySQL MHAMySQL MHA故障切换 1.案例分析 1.1.1案例概述 目前 MySQL 已经成为市场上主流数据库之一&#xff0c;考虑到业务的重要性&#xff0c;MySQL 数据库 单点问题已成为企业网站架构中最大的隐患。随着技术的发展&#xff0c;MHA…