FrontEnd/Vue
[Vue] Vue3 기반 프로젝트에서 카카오맵 API를 통해 지도를 뿌려보자. (2) 지도검색 및 지도 이동
모찌바라기
2022. 3. 9. 00:38
728x90
반응형
저번 글에 이어, 주소검색 및 지도이동을 구현하려고 한다 ( 해당 글 참조 )
카카오맵API에서 함수를 다 제공하기 때문에 그냥 가져다 쓰기만 하면 된다. 그냥 API연습 겸...
오늘은 MapHeader.vue를 중점적으로 보려고 한다.
우선 데이터를 담을 데이터 객체를 선언해보자.
data() {
return {
keyWord : '', // 검색키워드 v-model을 통해 검색단어를 받아옴
placeArray : [] // 검색결과를 담는 배열
}
},
그리고 실제로 API를 통해 주소검색을 하는 메서드를 선언한다.
searchBox : function(){
this.placeArray = []; // 배열 초기화
let places = new kakao.maps.services.Places(); // Places객체 초기화
let callback = (result, status) => { // 서버통신 콜백함수 선언
if (status === kakao.maps.services.Status.OK) {
this.placeArray = this.placeArray.concat(result); 배열에 데이터 담음
}
};
// 검색단어와 콜백함수를 인자로 하는 keywordSearch함수 호출
// 카카오맵API에서 지원하는 함수이므로 그냥 갖다 쓰기만 하면 됨
places.keywordSearch(this.keyWord, callback);
},
이렇게 까지 하면 검색은 잘 될 것이다..
근데 주의해야 할 건 카카오맵API에는 라이브러리가 3종류로 나뉘어져 있는데,
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=APIKEY&libraries=LIBRARY"></script>
<!-- services 라이브러리 불러오기 -->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=APIKEY&libraries=services"></script>
<!-- services와 clusterer, drawing 라이브러리 불러오기 -->
<script type="text/javascript" src="//dapi.kakao.com/v2/maps/sdk.js?appkey=APIKEY&libraries=services,clusterer,drawing"></script>
이렇게 3개가 있다. 주소검색은 services에 들어 있으므로, 2번째나 3번째 라이브러리를 가져와야 사용이 가능하다.
첫번째는 진짜 지도만 뿌려주는 라이브러리.. 왠만하면 그냥 3번째꺼 갖다 쓰자
이제 저 주소를 클릭했을 때 지도이동을 하는 함수를 호출하는데, 다음과 같이 함수를 선언하였다.
setLocation : function(item){ // item을 파라메터로 받음
let mapContainer = document.getElementById('kakaoMap'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
level: 3 // 지도의 확대 레벨
};
var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
var moveLatLon = new kakao.maps.LatLng(item.y, item.x);
// 지도 중심을 이동 시킵니다
map.setCenter(moveLatLon);
}
검색목록의 주소를 클릭하면 해당 위치로 이동한다.
오늘은 검색 및 지도이동을 하였다. 전부 헤더쪽에서만 작성하였고, 스크롤바 같은 기능은 안넣고 그냥
Height만 줄였다. 필요한 사람은 그냥 스크롤바 넣으면 될 듯.. 아래는 전체 코드이다.
MapHeader.vue
<template>
<header class="p-3 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<a href="/" class="d-flex align-items-center mb-2 mb-lg-0 text-white text-decoration-none">
<svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"/></svg>
</a>
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li><a href="#" class="nav-link px-2 text-secondary">Home</a></li>
<li><a href="#" class="nav-link px-2 text-white">Features</a></li>
<li><a href="#" class="nav-link px-2 text-white">Pricing</a></li>
<li><a href="#" class="nav-link px-2 text-white">FAQs</a></li>
<li><a href="#" class="nav-link px-2 text-white">About</a></li>
</ul>
<form class="col-12 col-lg-auto mb-3 mb-lg-0 me-lg-3" id="searchForm">
<input type="search" class="form-control form-control-dark" placeholder="Search..." v-model="keyWord" @change="searchBox" aria-label="Search">
<div class="d-flex gap-5 justify-content-center" id="dropdownFilter">
<div class="dropdown-menu pt-0 mx-0 rounded-3 shadow overflow-hidden" style="height:500px; width: 280px;" v-if="placeArray.length!=0">
<ul class="list-unstyled mb-0" v-for="item in placeArray" :key="item">
<a class="dropdown-item" href="#" @click="setLocation(item)">
<li>
<div class="d-flex align-items-center gap-2 py-2">
<span class="d-inline-block bg-success rounded-circle" style="width: .5em; height: .5em;"></span>
<div>{{item.place_name}}</div>
</div>
<div class="small">{{item.address_name}}</div>
</li>
</a>
</ul>
</div>
</div>
</form>
<div class="text-end">
<button type="button" class="btn btn-outline-light me-2">검색</button>
</div>
</div>
</div>
</header>
</template>
<script>
export default {
data() {
return {
keyWord : '',
placeArray : []
}
},
methods: {
searchBox : function(){
this.placeArray = [];
let places = new kakao.maps.services.Places();
let callback = (result, status) => {
if (status === kakao.maps.services.Status.OK) {
this.placeArray = this.placeArray.concat(result);
}
};
places.keywordSearch(this.keyWord, callback);
},
setLocation : function(item){
let mapContainer = document.getElementById('kakaoMap'), // 지도를 표시할 div
mapOption = {
center: new kakao.maps.LatLng(33.450701, 126.570667), // 지도의 중심좌표
level: 3 // 지도의 확대 레벨
};
var map = new kakao.maps.Map(mapContainer, mapOption); // 지도를 생성합니다
var moveLatLon = new kakao.maps.LatLng(item.y, item.x);
// 지도 중심을 이동 시킵니다
map.setCenter(moveLatLon);
}
},
}
</script>
<style>
.dropdown-menu {
display: block;
width: auto;
margin: 4rem auto;
}
.form-control-dark {
background-color: rgba(255, 255, 255, .05);
border-color: rgba(255, 255, 255, .15);
}
#dropdownFilter {
position: relative;
top: -55px;
left: 40px;
}
.small {
font-size: 11px;
margin-left: 17px;
}
</style>
728x90
반응형