Vue基于高德地图API封装一个地图组件

news2024/11/20 12:37:33
一、参考资料
 

高德开放平台 | 高德地图API (amap.com)
 

二、安装及配置
 

pnpm i @vuemap/vue-amap --save

man.ts      密钥及安全密钥需要自己到高德地图开放平台控制台获取.

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import vant from 'vant'
import 'vant/lib/index.css'
import VueAMap, { initAMapApiLoader } from '@vuemap/vue-amap'
import '@vuemap/vue-amap/dist/style.css'

import * as echarts from 'echarts'

initAMapApiLoader({
  key: '841d5250cb7f61adda2ee70c1e3abdaf',
  securityJsCode: 'd122cbf5a33de34356661cf0cef1a553', // 新版key需要配合安全密钥使用
  plugins: [
    // 定位空间,用来获取和展示用户主机所在的经纬度位置
    'AMap.Geolocation',
    // 输入提示插件
    'AMap.Autocomplete',
    // POI搜索插件
    'AMap.PlaceSearch',
    // 右下角缩略图插件,比例尺
    'AMap.Scale',
    // 地图鹰眼插件
    'AMap.OverView',
    // 地图工具条
    'AMap.ToolBar',
    // 类别切换空间,实现默认图层与卫星图,实施交通层之间切换的控制
    'AMap.MapType',
    // 编辑 折线多边形
    'AMap.PolyEditor',
    'AMap.CircleEditor',
    // 地图编码
    'AMap.Geocoder'
  ]
})

const app = createApp(App)
//全局挂载echarts
app.config.globalProperties.$echarts = echarts
app.use(router)
app.use(ElementPlus)
app.use(VueAMap)
app.use(vant)
app.mount('#app')
三、源码分享
 

1、map.vue

<template>
  <el-dialog v-model="showMapDialog">
    <template #default>
      <div id="container">
        <AmapSelect v-model="locationData" @callback="getMapInfo" />
      </div>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, nextTick, defineEmits } from 'vue'
// import { ElMessage } from 'element-plus';
import AmapSelect from './AmapSelect.vue'

const props = defineProps({
  title: {
    type: String,
    default: '选择位置'
  },

  center: {
    type: Array,
    default: () => [115.846381, 28.659961]
  }
})

const locationData:any = ref([])
const showMapDialog = ref(false)
const emit = defineEmits(['submit'])

function getMapInfo(info: any) {
  // console.log(info,'info'); 可拿到点击的地址 以及经纬度  可用于做回显等其他操作
  // debugger
  emit('submit', {
    address: info.address,
    lnglat: info.lnglat
  })
}

const openForm = () => {
  showMapDialog.value = true
  nextTick(() => {
    locationData.value=props.center;
  })
}

//提交

// const okModal = async () => {}

//导出方法

defineExpose({
  openForm
})
</script>

<style lang="scss" scoped>
#container {
  height: 400px;
}

.el-dialog__body {
  padding: 0 !important;
}
</style>

2、AmapSelect.vue

<template>
  <el-amap :zoom="zoom" @init="init">
    <el-amap-search-box
      :visible="visible"
      @select="selectChange"
      @choose="handleChange"
      placeholder="请输入"
    />

  </el-amap>
</template>

<script>
export default {
  name: 'AmapSelect',

  emits: ['callback'],

  props: {
    visible: {
      type: Boolean,
      default: true
    },

    modelValue: {
      type: Array,
      default: []
    }
  },

  data() {
    return {
      zoom: 12,
      map: null,
      geocoder: new AMap.Geocoder({}),
      activeAddress: null,
    }
  },

  watch: {
    modelValue: {
      handler(val, oldVal) {
        if (val) {
          // let lnglat = val[1].split(',')

          this.onClickMap({
            lnglat: { lng: val[0], lat: val[1] }
          })
        }
      },

      deep: true
    }
  },

  mounted() {},

  methods: {
    init(map) {
      this.map = map

      map.on('click', this.onClickMap.bind(this))
    },

    selectChange({ poi }) {
      if (poi.location) {
        let { lng, lat } = poi.location

        this.onClickMap(
          {
            lnglat: { lng, lat }
          },

          () => {
            this.map.setCenter([lng, lat])
          }
        )
      }
    },

    handleChange(e) {
      console.log('handleChange: ', e)
    }, 
    
    
    // 点击地图
    onClickMap(e, callback) {
      let lnglat = [e.lnglat.lng, e.lnglat.lat]

      var infoWindow = new AMap.InfoWindow({
        offset: new AMap.Pixel(0, 0)
      })

      this.geocoder.getAddress(lnglat, (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
          // result为对应的地理位置详细信息

          var province = result.regeocode.addressComponent.province //省

          var city = result.regeocode.addressComponent.city //市

          var district = result.regeocode.addressComponent.district //县区

          var township = result.regeocode.addressComponent.township //镇、街道

          var region = province + city + district + township //返回所属区域

          let addressName = result.regeocode.formattedAddress.replace(
            region,
            ''
          )

          let address = ''

          if (!addressName) {
            address = region

            addressName = region
          } else {
            address = result.regeocode.formattedAddress
          }

          let obj = {
            lnglat: lnglat.toString(),

            address: address,

            addressName: addressName
          }

          infoWindow.setContent(this.createdInfoWindowContent(obj))

          infoWindow.open(this.map, lnglat) // 更新数据

          callback && callback()
        }
      })

      this.map.setCenter(lnglat)
    }, 
    // 窗口信息
    createdInfoWindowContent(data) {
      var infoWindowContent =
        '<style>.btn {display: inline-block; font-weight: 400; text-align: center; white-space: nowrap; vertical-align: middle;' +
        '-webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; border: 1px solid transparent;' +
        'transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;' +
        'background-color: transparent; background-image: none; color: #25A5F7; border-color: #25A5F7; padding: .25rem .5rem; line-height: 1.5;' +
        'border-radius: 1rem;  -webkit-appearance: button; cursor:pointer;}</style>' +
        '<div className="custom-infowindow input-card">' +
        '<label  class="input-item-text">' +
        data.addressName +
        '</label>' +
        '<div class="input-item">' +
        '<div class="input-item-prepend">' +
        '<span style="color:grey">' +
        data.address +
        '</span>' +
        '</div>' +
        '</div>' + // 为 infowindow 添加自定义事件
        '<input id="lnglat2container" type="button" class="btn" value="选择地址" onclick="setLngLat()"/>' +
        '</div>'
        // debugger;

      window.setLngLat = () => {
        this.$emit('update:modelValue', [data.address, data.lnglat])
        this.$emit('callback', data)
      }

      return infoWindowContent
    }
  }
}
</script>

<style lang="scss" scoped>


</style>
四、效果展示

点击窗口信息的选择地址可拿到点击位置的信息然后再做后续操作!!!主要还是参考高德地图API的官方文档.

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Orange3数据可视化(组件概览)

概要 大家见过Orange3提供的丰富数据可视化组件吗&#xff1f; Orange3为您提供了一系列生动的图表工具&#xff0c;包括树图、箱线图、小提琴图、分布图、散点图、折线图、条形图、筛图、马赛克图、自由投影、线性投影、雷达图、热力图、韦恩图、轮廓图、毕达哥拉斯树、毕达哥…

Python | Leetcode Python题解之第48题旋转图像

题目&#xff1a; 题解&#xff1a; class Solution:def rotate(self, matrix: List[List[int]]) -> None:n len(matrix)# 水平翻转for i in range(n // 2):for j in range(n):matrix[i][j], matrix[n - i - 1][j] matrix[n - i - 1][j], matrix[i][j]# 主对角线翻转for …

鸿蒙内核源码分析(任务调度篇) | 任务是内核调度的单元

任务即线程 在鸿蒙内核中&#xff0c;广义上可理解为一个任务就是一个线程 官方是怎么描述线程的 基本概念 从系统的角度看&#xff0c;线程是竞争系统资源的最小运行单元。线程可以使用或等待CPU、使用内存空间等系统资源&#xff0c;并独立于其它线程运行。 鸿蒙内核每个…

OS对软件的管理,进程,PCB、子进程

进程 可执行程序加载到内存中&#xff0c;操作系统为内个程序都形成一个PCB对象&#xff08;结构体对象&#xff09;&#xff0c;PCB里存放着这个程序的所有的属性。进程可执行程序PCB &#xff0c;CPU执行程序也是先通过该程序的PCB找到相应的程序代码&#xff0c;然后一条一…

鸿蒙内核源码分析(时钟任务篇)

时钟概念 时间是非常重要的概念&#xff0c;我们整个学生阶段有个东西很重要,就是校园铃声. 它控制着上课,下课,吃饭,睡觉的节奏.没有它学校的管理就乱套了,老师拖课想拖多久就多久,那可不行,下课铃声一响就是在告诉老师时间到了,该停止了让学生HAPPY去了. 操作系统也一样&…

Flutter基础语法

Flutter概要 Flutter目录结构 文件夹 作用 android android 平台相关代码 ios ios平台相关代码 lib flutter相关代码&#xff0c;我们主要编写的代码就在这个文件夹中 test 用于存放测试的代码 pubspec.yaml 配置文件&#xff0c;一般存放一些第三方库的依赖 Flutt…

【研发管理】产品经理知识体系-产品设计与开发工具

导读&#xff1a;产品设计与开发工具的重要性体现在多个方面&#xff0c;它们对于产品的成功开发、质量提升以及市场竞争力都具有至关重要的影响。产品设计工具可以帮助设计师更高效地创建和优化产品原型。开发工具在产品开发过程中发挥着至关重要的作用。产品设计与开发工具还…

细致讲解——不同类型LSA是作用以及相互之间的联系

目录 一.常见的LSA类型 二.OSPF特殊区域 1.区域类型 2.stub区域和totally stub区域 &#xff08;1&#xff09;stub区域 &#xff08;2&#xff09;totally stub区域 3.nssa区域和totally nssa区域 &#xff08;1&#xff09;nssa区域 &#xff08;2&#xff09;totall…

tensorflow_decision_forests\tensorflow\ops\inference\inference.so not found

恰好有一个帖子提到了py3.10里面的解决方案 pip install --user tensorflow2.11.0My tensorflow version is 2.11.0 and my tensorflow_decision_forests version is 1.2.0 so those should be compatible. I also am using Python version 3.10.11原文链接&#xff1a; http…

基于SpringBoot+VueHome F家居系统的设计与实现

系统介绍 该Home F家居系统采用B/S架构、前后端分离以及MVC模型进行设计&#xff0c;并采用Java语言以及SpringBoot框架进行开发。本系统主要设计并完成了用户注册、登录&#xff0c;购买家具过程、个人信息修改等&#xff0c;商家添加家具信息、对家具进行发货&#xff0c;管理…

假定输入字符串只包含字母和*号。编写函数fun:只删除字符串前导和尾部的*号,串中字母之间的*号都不删除。

本文收录于专栏:算法之翼 https://blog.csdn.net/weixin_52908342/category_10943144.html 订阅后本专栏全部文章可见。 本文含有题目的题干、解题思路、解题思路、解题代码、代码解析。本文分别包含C语言、C++、Java、Python四种语言的解法完整代码和详细的解析。 题干 假定…

第10章:知识整合提示

这种技术使用模型的预先存在的知识&#xff0c;来整合新、旧信息&#xff0c;助力我们全面认知特定的主题。 与ChatGPT配合时&#xff0c;只需提供新信息与任务目标&#xff0c;加上清晰的提示词&#xff0c;它就能为你生成满意文本。 例 1:知识整合 任务&#xff1a;将新信息…

YOLOv9最新改进系列:完美融合即插即用的涨点模块之注意力机制(SEAttention)。

YOLOv9最新改进系列&#xff1a;完美融合即插即用的涨点模块之注意力机制&#xff08;SEAttention&#xff09;。 YOLOv9原文链接戳这里&#xff0c;原文全文翻译请关注B站Ai学术叫叫首er B站全文戳这里&#xff01; 详细的改进教程以及源码&#xff0c;戳这&#xff01;戳这…

QingHub Studio快速部署

简要介绍 QingHub Studio部署套件&#xff0c;主要针对需要本地化离线部署的用户提供一键部署的能力。目前本地化部署只支持单机版。需高可用部署的可以自行研究或寻求轻云研发团队技术支持。本地部署只作为用户开发的前后端应用的运行环境&#xff0c;不包括应用设计及监控运…

(22408)武汉大学计算机专硕初试备考经验贴

首先谈一下&#xff0c;写这篇文章的初衷。 我相信考武大计算机的同学都是优秀的&#xff0c;应该有自己的备考方法&#xff0c;所以这里并不介绍具体怎么备考某一科目。 计算机考研热度较高&#xff0c;备考不易&#xff0c;这里将自己备考过程中遇到的问题&#xff0c;分享…

(六)小案例银行家应用程序-删除账号-findindex方法

findindex方法和find方法非常类似&#xff0c;只不过findindex顾名思义&#xff0c;他返回的是index&#xff1b; ● 下面我们使用删除账号的功能来学习一下findindex的 ● 当用户登录成功之后&#xff0c;可以在下方输入自己的用户名和密码&#xff0c;然后提交&#xff0c…

【C++】类和对象完结篇——日期类实现

再谈构造函数 构造函数体赋值 在创建对象时&#xff0c;编译器通过调用构造函数&#xff0c;给对象中各个成员变量一个合适的初始值 class Date { public:Date(int year, int month, int day){_year year;//只能是说是赋初始值&#xff0c;不能说初始化_month month;_day …

【Flutter】GetX

前言 状态管理 / 路由管理 / 依赖管理 这三部分之间存在联系 参考文章 建议看官网文章&#xff0c;很详细 &#xff0c;pub.dev搜索get pub.dev的文档 状态管理文章相关链接 状态管理 案例 实现一个计算器&#xff0c;运用GetX去管理它 构建界面 构建一个计算器界面 …

Vue入门到关门之Vue介绍与使用

一、vue框架介绍 1、什么是Vue&#xff1f; Vue (读音 /vjuː/&#xff0c;类似于 view) 是一套用于构建用户界面的渐进式框架。与其它大型框架不同的是&#xff0c;Vue 被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff0c;不仅易于上手&#xff0c;还便于与…

软件测试(Web自动化测试)(二)

一.Selenium WebDriver的基本应用 &#xff08;一&#xff09;安装浏览器驱动 1.关闭浏览器的自动更新功能 以Windows7&#xff08;64位&#xff09;操作系统为例&#xff0c;讲解如何关闭Chrome浏览器的自动更新。首先按下快捷键“WinR”&#xff0c;打开运行对话框&#x…