최근에 프로젝트를 작성할 때 지도에서 해당 지점을 클릭하면 해당 정보를 표시할 필요가 있었는데, 팝업창이 꽤 화려해 보입니다. 팝업창 커스터마이징 방법은 오토나비 공식 홈페이지 및 기타 주요 플랫폼에서 알아봤는데 대부분 JS를 통한 HTML 구조로 작성되어 있어 레이아웃이 좋지 않을 뿐만 아니라 가독성 및 유지 보수성 HTML을 직접 작성하는 것이 좋습니다. 그래서 이 팝업창을 HTML로 쓸 수 있을까?
대답은: 예 !
렌더링은 다음과 같습니다.
먼저 아이디어에 대해 이야기하자면 AutoNavi Maps의 공식 문서에서 InfoWindow에 대한 소개를 읽어보면 정보 팝업창의 표시 내용이 HTML 요소 문자열 또는 HTMLElement 객체가 될 수 있음을 알 수 있습니다 . this.$refs
그래서 Vue에서 요소의 DOM 노드를 가져올 수 있지 않을까요 ? 그런 다음 첫 번째 시도를 시작했습니다.
먼저 백그라운드에서 반환된 데이터 유형을 살펴보세요.
data: [
{
id: '1', //id
projectName: 'xxxx项目', //项目名称
address: '山东省济南市市中区xxxxxxxxxx', //项目地址
sketchMapUrl: '116.998232,36.651352', //项目坐标
startDate: '2022-06-18', //计划开始日期
completedDate: '2022-11-18', //计划结束日期
progress: '78', //施工进度
buildPeople: '32', //施工人员
alarmNum: '8' //告警信息数目
},{
id: '2', //id
projectName: 'xxxx项目', //项目名称
address: '山东省济南市市中区xxxxxxxxxx', //项目地址
sketchMapUrl: '116.998232,36.651352', //项目坐标
startDate: '2022-06-18', //计划开始日期
completedDate: '2022-11-18', //计划结束日期
progress: '78', //施工进度
buildPeople: '32', //施工人员
alarmNum: '8' //告警信息数目
}
],
이 데이터 유형을 보았을 때 방금 v-for를 사용하지 않았습니까? 하지만 이때 문제가 발생합니다. 백그라운드에서 반환된 데이터를 직접 루프할 수 없습니다!
두 가지 이유가 있습니다.
- Gaode 맵의 AMap.InfoWindow 콘텐츠 속성은 여러 DOM 루트 노드를 지원하지 않습니다.
- 사용자가 어느 지점을 클릭했는지 알 수 없음
사용자가 클릭하는 지점을 결정하려면 필터링해야 합니다.
this.data.map((item) => {
this.arr = item.sketchMapUrl.split(',')
//自定义点图标
this.marker = new AMap.Marker({
map: this.map,
icon: this.icon,
position: [this.arr[0], this.arr[1]],
offset: new AMap.Pixel(-13, -30),
//注意,我这里判断是给点加了个额外的参数,就是数据的id
extData: item.id
})
this.marker.on('click', (e) => {
this.singleData = []
//这里通过e.target._opts.extData和item.id进行比对,如果相同则把这项点的信息单独放一个数组里去遍历,就是html里的遍历数组
if (e.target._opts.extData === item.id) {
this.singleData.push(item)
}
this.infoWindow.open(this.map, e.target.getPosition())
})
})
이때 클릭 포인트를 판단할 수 있으며, 다음 단계는 커스텀 팝업창을 구현하는 것입니다.
아래와 같이 코드 쇼:
<template>
<div class="web-box">
<!-- 地图 -->
<div id="map"></div>
<!-- 地图弹窗 -->
<div ref="infoWindow" class="infoWindow" >
<div class="container" v-for="(item,index) in singleData" :key="index">
<!-- 这里面写弹窗布局样式 -->
</div>
</div>
</template>
js 코드:
//自定义信息窗体
this.infoWindow = new AMap.InfoWindow({
isCustom: true,
autoMove: true,
avoid: [20, 20, 20, 20],
content: this.$refs.infoWindow,
closeWhenClickMap: true,
offset: new AMap.Pixel(16, -30)
})
this.$refs.infoWindow
팝업 노드를 HTML로 작성하여 콘텐츠에 넣으면 이와 같은 코드를 작성할 필요 가 없습니다 innerHTML
!appendChild