vue+百度地图选点封装:让地图选点变得更简单

前言

随着互联网的发展,地图应用已经成为了人们生活中不可或缺的一部分。而在开发中,如何快速、方便地实现地图选点功能,成为了一个备受关注的问题。本文将介绍如何使用百度地图和 vue,快速地实现地图选点功能,并将其封装成一个可复用的组件。无论是开发地图应用,还是需要在项目中使用地图选点功能,本文都将为大家提供一些有用的参考。


准备工作

1. 首先你需要注册一个百度账号,登录百度地图开放平台。可参考官方开发文档

在这里插入图片描述


2. 右上角点击进入控制台,申请注册成为开发者。

在这里插入图片描述
提交后在 『应用管理』–『我的应用』 中拿到申请密钥(ak)

在这里插入图片描述


3. 在 public 目录下 index.html 文件,添加如下引用

<script type="text/javascript" src="https://api.map.baidu.com/api?v=3.0&ak=你的密钥"></script>

4. npm

npm i vue-baidu-map --save

main.js 注册

import BaiduMap from 'vue-baidu-map'
Vue.use(BaiduMap,{
    
    ak:'你的密钥'})

实现思路

  1. 引入百度地图 API
  2. vue 组件中创建地图容器;
  3. 初始化地图,并添加地图控件;
  4. 监听地图点击事件,获取点击位置的经纬度;
  5. 在地图上添加标记,并将标记位置设置为点击位置;
  6. 逆向解析经纬度从而拿到详细的地址;
  7. 将标记位置的经纬度及详细地址保存到变量中传递。

话不多说,下面直接进入实战环节


封装文件

<template>
  <div>
    <el-dialog :close-on-click-modal="false" :visible.sync="dialogVisible" width="80%">
      <baidu-map @moving="syncCenterAndZoom" @moveend="syncCenterAndZoom" @zoomend="syncCenterAndZoom" class="bm-view" :center="center"
        :zoom="zoom" :scroll-wheel-zoom="true" @click="getClickInfo">
        <bm-marker :position="{lng: center.lng, lat: center.lat}" :dragging="true" animation="BMAP_ANIMATION_BOUNCE">
        </bm-marker>
        <bm-control :offset="{width: '10px', height: '10px'}">
          <bm-auto-complete v-model="keyword" :sugStyle="{zIndex: 9999}">
            <input type="text" placeholder="请输入搜索关键字" class="serachinput">
          </bm-auto-complete>
        </bm-control>
        <bm-local-search :keyword="keyword" :auto-viewport="true" style="width:0px;height:0px;overflow: hidden;"></bm-local-search>
      </baidu-map>
      <div class="btnBox">
        <el-button size="medium" type="primary" @click="confirm">确定</el-button>
      </div>
    </el-dialog>
  </div>
</template>
<script>
export default {
      
      
  data: function () {
      
      
    return {
      
      
      dialogVisible: this.value, //弹框显隐
      keyword: "", //搜索关键字
      center: {
      
       lng: 116.404555, lat: 39.915599 }, //经纬度
      zoom: 13, //缩放级别
      address: "", //详细地址
      point: {
      
       lng: 116.404555, lat: 39.915599 }, //经纬度
    };
  },
  props: {
      
      
    value: Boolean,
  },

  methods: {
      
      
    // 打开弹框
    revealShow() {
      
      
      this.dialogVisible = true;
    },
    // 点击地图
    getClickInfo(e) {
      
      
      this.center.lng = Number(e.point.lng).toFixed(6);
      this.center.lat = Number(e.point.lat).toFixed(6);
      this.geocAddress(e.point);
    },
    // 地图缩放、地图缩放、移动过程中持续触发
    syncCenterAndZoom(e) {
      
      
      const {
      
       lng, lat } = e.target.getCenter();
      this.center.lng = Number(lng).toFixed(6);
      this.center.lat = Number(lat).toFixed(6);
      this.zoom = e.target.getZoom();
      this.geocAddress(e.target.getCenter());
    },
    // 逆向解析地址
    geocAddress(point) {
      
      
      let that = this;
      var geoc = new BMap.Geocoder();
      geoc.getLocation(point, function (geocInfo) {
      
      
        if (geocInfo) {
      
      
          let detailsInfo = geocInfo.addressComponents;
          let address =
            detailsInfo.province +
            detailsInfo.city +
            detailsInfo.district +
            detailsInfo.street +
            detailsInfo.streetNumber;
          if (geocInfo.surroundingPois.length > 0) {
      
      
            address = address + geocInfo.surroundingPois[0].title;
          }
          that.address = address;
          that.point = point;
        }
      });
    },
    // 确认
    confirm() {
      
      
      this.dialogVisible = false;
      this.$emit("confirmOn", this.point, this.address);
    },
  },
};
</script>
 
<style scoped>
.bm-view {
      
      
  width: 100%;
  height: 60vh;
}
.serachinput {
      
      
  margin: 10px;
  width: 300px;
  border: none;
  border-radius: 4px;
  padding: 0px 10px;
  height: 40px;
  line-height: 40px;
  border: 1px solid #dcdfe6;
  color: #606266;
}
.btnBox {
      
      
  margin-top: 20px;
  display: flex;
  justify-content: right;
}
/* 去除百度地图的图标 根据实际情况看是否要加样式穿透 */
/* ::v-deep .anchorBL {
  display: none !important;
} */
</style>

使用文件

<template>
  <div>
    <el-card class="box-card">
      <div style="margin-bottom:10px">
        <p>经度:{
   
   {center.lng ? center.lng : "--"}}</p>
        <p>维度:{
   
   {center.lat ? center.lat : "--"}}</p>
        <p>地址:{
   
   {address ? address : "--"}}</p>
      </div>
      <el-button size="mini" type="primary" @click="openMapDialog">打开地图</el-button>
    </el-card>
    <!-- 地图组件 -->
    <div>
      <geographicalMap @confirmOn="ensureOn" ref="bmapAddressSelect"></geographicalMap>
    </div>
  </div>
</template>
<script>
import geographicalMap from "./mapView";
export default {
      
      
  components: {
      
      
    geographicalMap,
  },
  data() {
      
      
    return {
      
      
      center: {
      
       lng: "", lat: "" },
      address: "",
    };
  },
  methods: {
      
      
    // 打开地图
    openMapDialog() {
      
      
      this.$refs.bmapAddressSelect.revealShow();
    },
    // 确定
    ensureOn(center, address) {
      
      
      this.center = center;
      this.address = address;
    },
  },
};
</script>

实现效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Shids_/article/details/131171297