Vue 3 환경에서 개발하고 있으며, 어떤 이유지는 모르겠으나 위 코드로 Local 환경에서는 지도가 여러번 그려지지 않는 것을 확인했습니다
문제는 npm run build
했을 때(빌드 파일)는 여러번 그려지는 부분을 막는 부분이 제대로 동작하지 않아 문의를 드리게 되었습니다
현재 public\index.html
에는 따로 kakao map api script를 등록해 두지 않은 상태이며 kakaoMapPage.vue에다가 모든 코드를 작성한 상태입니다. 다른 컴포넌트 2개에서 kakaoMapPage.vue를 자식 컴포넌트로 두고 있습니다
kakaoMapPage.vue에서 지도 그리기 전에 this.map = null로 초기화 하는 방법으로도 시도해 보았지만 작동하지 않았습니다
구글링 하다가 kakao map api를 빌드하여 사용하려면 무조건 index.html에다가 선언해야 한다는 글을 보았는데, index.html에 <script src="//dapi.kakao.com/v2/maps/sdk.js?autoload=false&appkey=<%= process.env.VUE_APP_KAKAOMAP_KEY %>"></script>
이렇게 선언해 놓는다고 해도 그 다음에는 어떻게 접근해야 할 지 도저히 감이 오질 않아 도움 요청드립니다
아래는 코드 일부분 입니다. 불 필요한 부분은 삭제했습니다
<template>
<div id="map"></div>
</template>
<script>
import FadeLoader from 'vue-spinner/src/FadeLoader.vue';
var imageSrc = require('@/assets/mapMarker.svg');
export default {
props: ['cameraInfoList', 'newCameraInfoList'],
components: {
FadeLoader,
},
data() {
return {
cameraName: '',
tempThumbailArr: [],
thumnailArr: [], // base64 img
totalThumbnailCount: 0,
videoFlag: false,
map: null, // 전역 map 변수 선언
loadingFlag: false,
tempCount: 0, // thumbnail count 용
markers: [], // to remove markers
overlays: [], // to remove overlays
modalFlag: null,
modal: null,
lat: 36.368889,
lon: 126.976667,
zoom: 13,
cameraSerial: null,
equalPositionCameraList: [],
};
},
mounted() {
if (!window.kakao || !window.kakao.maps) {
const script = document.createElement('script');
script.src = `//dapi.kakao.com/v2/maps/sdk.js?autoload=false&appkey=${process.env.VUE_APP_KAKAOMAP_KEY}`;
script.addEventListener('load', () => {
console.log('Loaded.', window.kakao);
kakao.maps.load(this.initMap);
});
document.head.appendChild(script);
} else {
console.log('It has already been loaded.', window.kakao);
this.initMap();
}
this.$socket.client.emit('thumnail', this.$socket.client.id);
console.log('emit');
},
methods: {
initMap() {
/* global kakao */
const container = document.getElementById('map');
const options = {
mapTypeId: kakao.maps.MapTypeId.HYBRID,
center: new kakao.maps.LatLng(this.lat, this.lon),
level: this.zoom,
};
this.map = new kakao.maps.Map(container, options);
this.map.setMaxLevel(13);
this.mapMarkerMethods();
},
getLatLon(lat, lon) {
this.map.setLevel(3);
this.map.setCenter(new kakao.maps.LatLng(lat, lon));
},
getThumnail(vm) {
this.$socket.client.on('reqthumnail', function (info) {
vm.tempCount = 0; // 실제 배열에 들어간 값 count 를 위한 변수
vm.tempThumbailArr.forEach((element) => {
vm.tempCount++;
});
if (info.total === vm.tempCount) {
// backend 에서 넘어온 totalCount 와 실제 값 count 같을 때,
vm.thumnailArr = vm.tempThumbailArr;
// Reset
vm.markers.forEach((ele) => {
ele.setMap(null);
});
vm.markers = [];
vm.overlays.forEach((ele) => {
ele.setMap(null);
});
vm.overlays = [];
vm.mapMarkerMethods();
vm.tempThumbailArr = [];
}
});
},
mapMarkerMethods() {
var imageSize = new kakao.maps.Size(24, 35); // 에러 발생
var markerImage = new kakao.maps.MarkerImage(imageSrc, imageSize);
var vm = this;
// for (let i = 0; i < this.cameraInfoList.length; i++) {
// var data = this.cameraInfoList[i];
for (let i = 0; i < this.newCameraInfoList.length; i++) {
var data = this.newCameraInfoList[i];
var thumnail = this.thumnailArr[i];
if (this.thumnailArr.length === 0) {
displayMarker(data, undefined, this.map, i);
} else {
var temp = this.thumnailArr.find(
(ele) => ele.url === this.newCameraInfoList[i].serial
);
displayMarker(data, temp.image, this.map, i);
}
}
function displayMarker(data, thumnail, map, i) {
vm.markers[i] = new kakao.maps.Marker({
map,
position: new kakao.maps.LatLng(data.lat, data.lon),
image: markerImage,
});
vm.overlays[i] = new kakao.maps.CustomOverlay({
yAnchor: 1.4,
position: vm.markers[i].getPosition(),
});
var wrap = document.createElement('div');
wrap.className = 'info card card-sm';
var content = document.createElement('div');
var tempSrc;
if (thumnail === undefined) {
tempSrc = require('@/assets/firewatcher/imgLoading.svg');
} else {
tempSrc = thumnail;
}
content.innerHTML = `
<img src="${tempSrc}" id="thumbnail" onerror="this.onerror=null; this.src='${require('@/assets/firewatcher/imgLoading.svg')}'" width="170" height="90" style="border-radius: 8px" />
`;
wrap.appendChild(content);
vm.overlays[i].setContent(wrap);
vm.overlays[i].setMap(map);
kakao.maps.event.addListener(vm.markers[i], 'click', function () {
vm.equalPositionCameraList = [];
vm.cameraInfoList.find((element) => {
if (element.keyLonLat === data.keyLonLat) {
vm.equalPositionCameraList.push(element);
}
});
if (vm.equalPositionCameraList.length > 1) {
vm.modal = new bootstrap.Modal('#equalPositionCameraModal', {
backdrop: 'static',
keyboard: false,
});
vm.modal.show();
} else {
vm.openVideoModal(data);
}
});
// hover event
kakao.maps.event.addListener(vm.markers[i], 'mouseover', function () {
vm.markers[i].setZIndex(1);
vm.overlays[i].setZIndex(1);
});
kakao.maps.event.addListener(vm.markers[i], 'mouseout', function () {
vm.markers[i].setZIndex(0);
vm.overlays[i].setZIndex(0);
});
}
},
};
</script>
<style scoped>
#map {
height: 100%;
}
</style>