vue3 + 高德地图 实现多个标点和窗体,超详细,开箱即用

在高德API的使用中,有很多比较实用的技术,今天就整理一下高德地图实现标点与点击标点展示弹出框的写法。开箱即用 

对于创建地图这些我就不说明了 直接上代码 首先做一个地图标点。

import img1 from "@/assets/img/shizheng.png";
import img2 from "@/assets/img/gaocen.png";
import img3 from "@/assets/img/jikeng.png";
import img4 from "@/assets/img/suidao.png"; //这个地方引入标点的图片方便后面使用


const icon2 = new AMap.Icon({
  size: new AMap.Size(40, 40), // 图标尺寸
  image: img1, // Icon的图像
  imageOffset: new AMap.Pixel(0, 0), // 图像相对展示区域的偏移量,适于雪碧图等
  imageSize: new AMap.Size(35, 35), // 根据所设置的大小拉伸或压缩图片
});//这里是new了一个ico实例,供地图使用,这里只展示一个 

const getmapList = async (value: any) => {
  const data = await xxx({ projectType: value });//发送接口请求数据,也就是坐标
  if (data.length == 0) return;
  //把地图缩放比例还原到14, 默认定义到接口的第一个经纬度
  state.map.setZoomAndCenter(14, [data[0].projectLong, data[0].projectLat]);
  state.marker = [] as any;//这里的state.map就是地图实例
//这里循环请求到的数组 将每一个点的经纬度push到高德实例中取
  data.map((e: any) => {
    state.marker.push(
      new AMap.Marker({
        position: [e.projectLong, e.projectLat],//坐标
        title: e.projectName,//点名字
        id: e.id,//点ID
        icon: eval("icon" + value),//点的图片,这里就是上面的icon2,根据getmapList的传参控制展示哪一个ico
      })
    );
  });
//这里是循环添加点击事件,将每一个点都注册一变
  for (var i = 0; i < state.marker.length; i++) {
    state.marker[i].on("click", clickHandler);
  }
//生成地图
  state.map.add(state.marker);
};

现在地图标点标好了,点的点击事件也注册好了,在接着我们说一下点击事件的内容,也就是创建窗体。

//点击标点展示详情
const clickHandler = async (e: any) => {
   //点击事件传过来的是经纬度,触发后直接缩放到14设置该点为中心点
  state.map.setZoomAndCenter(14, [e.lnglat.lng, e.lnglat.lat]);
  // 创建自定义的信息窗体内容元素
  let titleList = {} as any;
  const res = await xxx({ id: e.target.De.id });//通过接口拿到窗体要展示的数据
  titleList = res[0];
  titleList.projectBuildNames = titleList.projectBuildName;
  titleList.projectNames = titleList.projectName;
    //由于数据不规范 所以这里做了一些处理
  if (titleList.projectBuildNames.length > 10) {
    titleList.projectBuildName =
      titleList.projectBuildNames.substring(0, 10) + "...";//这里是数据超过10个截取加省略号
  }
  if (titleList.projectNames.length > 13) {
    state.boot = true;
    titleList.projectName = titleList.projectNames.substring(0, 13) + "...";
  }
  const list = titleList.projectStartDate.split("-");//这里是对时间前做处理
  titleList.projectStartDate = list[0] + "年" + list[1] + "月" + list[2] + "日";
  const contentElement = document.createElement("div");//这里就是创建Dome元素
  contentElement.className = "custom-info-window";//给Dome设置类方便操作
    //这里就是在该元素上插入html模板字符串,也就是做的窗体了
  contentElement.innerHTML = `
      <div class="content">
        <h4 class="tbg" style="font-size:1vw" >${titleList.projectName}<span                                 class="closeSpan" onclick="closeClick()">x</span></h4>
        <div><span>工程状态: </span><span style="color:orange">${titleList.projectStatus}</span></div>
        <div><span>项目所在地: </span>${titleList.projectAddress}</div>
        <div onmouseover="hover()" onmouseout="out()"><span>承建单位: </span>${titleList.projectBuildName}</div>
        <div><span>项目负责人: </span>${titleList.projectHead}</div>
        <div><span>开工日期: </span><span style="font-family: 'DS-Digital'">${titleList.projectStartDate}</span></div>
        </div>
       
    `;
  //创建信息窗体,也就是将上面做的窗体插入地图实例
  const infoWindow = new AMap.InfoWindow({
    isCustom: true, //使用自定义窗体
    content: contentElement,
    offset: new AMap.Pixel(70, -25),
  });
  infoWindow.open(state.map, [e.lnglat.lng, e.lnglat.lat]);
};

同时呢做了一个点击关闭功能

onBeforeMount(()=>{
//地图信息详情关闭按钮在onBeforeMount注册
  window.closeClick = () => {
    state.map.clearInfoWindow();
  };
})  

这里呢就是我弹窗的一些样式,仅供参考

:deep(.custom-info-window) {
  width: 17vw;  
  height: 23vh;
  color: aqua;
  text-align: left;
  box-shadow: 3px 3px 3px #000;
  background-color: transparent !important;
  background: url("@/assets/img/弹框背景.png") no-repeat center bottom;
  background-size: 100% 100%;
  background-blend-mode: multiply;
  .content {
    .tbg{
      width: 17vw;
      padding-left: 1vh;
      height: 3vh;
      background: url("@/assets/img/弹框表头.png") no-repeat center bottom;
      background-size: 100% 100%;
      background-blend-mode: multiply;
      background-position: -1vh 0;
    }
    font-size: 1vw;
    position: absolute;
    div{
      margin-top: .7vh;
      padding-left: 1vh;

    }
    p {
      margin: 1px 2px;
    }
    h4 {
      margin: 1px 0px;
      font-size: 14px;
      position: relative;
      margin-bottom: 1vh;
      .closeSpan {
        position: absolute;
        top: -2%;
        right:5%;
        font-size: 1vw;
        font-weight: 400;
        color: #fff;
        cursor: pointer;
      }
    }
    .btnDiv {
      height: 25px;
      width: 100%;
    }
    .route-button {
      outline: none;
      font-size: 12px;
      border: 0px;
      width: 50px;
      height: 20px;
      padding: 0px;
      border-radius: 2px;
      float: right;
      color: white;
      background-color: rgba(255, 255, 255, 0.4);
      overflow: hidden;
    }
  }
 
}

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

J小C=

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值