[TIL] Vue - Kakao Map API (1)

jeongjwon·2024년 1월 15일
0

Vue

목록 보기
12/19

참고 : https://www.youtube.com/watch?v=BYT0zR2lbXQ&t=929s

Kako Map API

step 1. kakao developers 어플리케이션 추가하기

https://developers.kakao.com/ 에서 시작하기 버튼을 눌러

api 사용 권한을 받기 위해 정보를 입력한다.

내 애플리케이션>앱 설정>요약 정보 를 통해 앱을 구현할 때 필요한 키들을 획득할 수 있다.







step 2. JavaScript API 불러오기

kakao map api 를 잘 사용하기 위한 가이드 홈페이지에 나와있는 순서 중에서 vue 파일 내에 step 1 에서 발급받은 javascript api key 를 넣어주어야 사용할 수 있다.

public 폴더 > index.html 폴더의 head 태그 안에 script 태그 코드를 삽입해준다.









step 3. 지도 띄우기

지도를 띄우기 위해서는 지도를 담을 영역을 먼저 만들어준다.

<template>
  <div ref="map"></div>
</template>



그 영역 안에서 지도를 띄우기 위해서는 지도의 중심좌표를 가리키는 center와 확대 축소의 정도를 가리키는 level 의 옵션이 필요하다. 이 옵션을 가지고 지도를 생성하고 리턴한다.

공식 가이드에 나와있는 container 는 var container = this.$refs.map; 로 지도를 담을 영역을 가리킨다.

mounted(){
	let kakao = window.kakao;
      var container = this.$refs.map;
	const { center, level } = this.options;

    this.mapInstance = new kakao.maps.Map(container, {
      center: new kakao.maps.LatLng(center.lat, center.lng),
      level,
    }); //지도 생성 및 객체 리턴
}

전체코드는 마운트가 될 때 지도 영역이 나오도록 한다.









step 4. 지도 확대 축소하기

<template>
 <div class="controll">
      <button @click="zoom(1)">
        <span class="material-symbols"> zoom_in </span>
      </button>
      <button @click="zoom(-1)">
        <span class="material-symbols"> zoom_out </span>
      </button>
 </div>
</template> 
methods: {
    zoom(delta) {
      const level = Math.max(3, this.mapOption.level + delta);
      this.mapOption.level = level;
      console.log("zoom", this.mapOption.level);
    },
}

지도를 확대, 축소하기 위해 버튼 두 개를 생성하여 클릭시 zoom 함수가 구현된다.
zoom 함수는 현재 옵션의 level 에서 매개변수로 받아온 값 1 이나 -1값을 연산하여 옵션의 level 를 갱신해준다.

watch: {
    "options.level"(cur, prev) {
      console.log(`[LEVEL CHANGED] ${prev} => ${cur}`);
      this.mapInstance.setLevel(cur);
    },
}

watch 감시자를 통해 옵션의 level 의 변경이 감지가 되면 setLevel 메서드를 통해 매개변수로 전달해온 갱신된 level 값을 확대 수준을 설정한다.




💡 sass-lodaer 오류 해결하기

<style lang="scss">
button {
  border: 1px solid transparent;
  padding: 6px;
  background-color: #efefefdd;
  border-radius: 6px;
  &:hover {
    background-color: #ddd;
    border-color: #ddd;
    cursor: pointer;
  }
  &:active {
    background-color: #aaa;
    border-color: #aaa;
  }
}
</style>

다음과 같이 lang="scss" 버전으로 사용하고 npm install sass-loader 를 설치를 해주었지만, 이와 같은 오류가 발생했다.

구글링을 해서 찾아보니 다음과 같이 npm install sass-loader 가 아닌 npm install -D sass-loader@^10 sass 를 설치해줌으로써 오류를 해결하였다.






실행 화면









step 5. 지도 중심 이동시키기

지도의 중심을 변경하기 위해서는 옵션의 center 의 변경이 있어야 한다.
다음과 같이 세 개의 더미데이터를 이용해 가져온 값을 클릭시 지도의 중심이 변경하고자 한다.

//api.js
const api = {
  harbor: {
    all(callback) {
      const harbors = [
        {
          seq: 398,
          place: "제주항 국제 여객 터미널",
          lat: 33.52456237850086,
          lng: 126.54371888191963,
        },
        {
          seq: 399,
          place: "통영항",
          lat: 34.83952733985843,
          lng: 128.42015935198992,
        },
        {
          seq: 400,
          place: "부산 국제 크루즈 터미널",
          lat: 35.07980714092641,
          lng: 129.0798233676466,
        },
      ];
      callback({ success: true, harbors });
    },
  },
};

export default api;
import api from "./service/api";
 mounted() {
    api.harbor.all((res) => {
      console.log("[항구목록]", res.harbors);
      this.harbors = res.harbors;
    });
  },

따라서 마운트 될 때, api 를 가져와져와 결과값을 받아오면 harbors 배열값에 저장시킨다.

 <div class="map-area">
 	<div class="harbors">
      	<div
          class="harbor"
          v-for="hbr in harbors"
          :key="hbr.seq"
          @click="showOnMap(hbr)">
          <h3>{{ hbr.place }}</h3>
        </div>
    </div>
 </div>

배열값을 v-for 을 이용해 바운딩하여 나열시킨다.
배열 안 각자의 객체 값은 아래와 같다.

 {
          seq: 400,
          place: "부산 국제 크루즈 터미널",
          lat: 35.07980714092641,
          lng: 129.0798233676466,
 },
methods: {
  showOnMap(harbor) {
      console.log(harbor);
      this.mapOption.center = {
        lat: harbor.lat,
        lng: harbor.lng,
      };
    },
  },
}

그 place 값을 클릭했을 때 이벤트 showOnMap 함수는 객체값의 lat 와 lng 을 옵션의 center 값으로 지정해준다.

위의 지도 확대 축소에서 확대 축소 정도를 나타내는 Level를 watch 감시자를 통해 설정해주었다면, 이도 마찬가지로 center 를 watch 감시자와 setCenter 메서드를 통해 설정해줄 수 있다.

watch:{
	"options.center"(cur, prev) {
     //console.log(`[NEW CENTER]`, cur.lat, cur.lng);
     this.mapInstance.setCenter(new kakao.maps.LatLng(cur.lat, cur.lng));
   },
},





실행 화면









전체 코드

⭐️ 파일 경로


App.vue
<template>
  <div>
    <h3>kakao map demo(center, level)</h3>
    <div class="controll">
      <button @click="zoom(1)">
        <span class="material-symbols"> zoom_in </span>
      </button>
      <button @click="zoom(-1)">
        <span class="material-symbols"> zoom_out </span>
      </button>
    </div>
    <div class="map-area">
      <div class="harbors">
        <div
          class="harbor"
          v-for="hbr in harbors"
          :key="hbr.seq"
          @click="showOnMap(hbr)"
        >
          <h3>{{ hbr.place }}</h3>
        </div>
      </div>

      <KakaoMap class="kmap" :options="mapOption" />
    </div>
  </div>
</template>

<script>
import KakaoMap from "./components/map/KakaoMap.vue";
import api from "./service/api";
export default {
  components: {
    KakaoMap,
  },
  data() {
    return {
      mapOption: {
        center: {
          lat: 33.450701,
          lng: 126.570667,
        },
        level: 8,
      },
      harbors: [],
    };
  },
  mounted() {
    api.harbor.all((res) => {
      console.log("[항구목록]", res.harbors);
      this.harbors = res.harbors;
    });
  },
  methods: {
    zoom(delta) {
      const level = Math.max(3, this.mapOption.level + delta);
      this.mapOption.level = level;
      console.log("zoom", this.mapOption.level);
    },
    showOnMap(harbor) {
      console.log(harbor);
      this.mapOption.center = {
        lat: harbor.lat,
        lng: harbor.lng,
      };
    },
  },
};
</script>

<style lang="scss">
button {
  border: 1px solid transparent;
  padding: 6px;
  background-color: #efefefdd;
  border-radius: 6px;
  &:hover {
    background-color: #ddd;
    border-color: #ddd;
    cursor: pointer;
  }
  &:active {
    background-color: #aaa;
    border-color: #aaa;
  }
}
.map-area {
  display: flex;
  .harbors {
    .harbor {
      padding: 10px;
      border: 1px solid transparent;
      &:hover {
        background-color: aliceblue;
        border-color: #6a9dff;
        cursor: pointer;
      }
      &:active {
        background-color: rgb(166, 197, 224);
        border-color: #4471c5;
      }
      h4 {
        margin: 0;
      }
    }
  }
  .kmap {
    flex: 1 1 auto;
  }
}
</style>




KakaoMap.vue
<template>
  <div ref="map"></div>
</template>

<script>
let kakao = window.kakao;
export default {
  props: ["options"],
  data() {
    return {
      mapInstance: null,
    };
  },
  mounted() {
    console.log(this.options);
    kakao = kakao || window.kakao;
    console.log(this.$refs.map);

    var container = this.$refs.map;

    const { center, level } = this.options;

    this.mapInstance = new kakao.maps.Map(container, {
      center: new kakao.maps.LatLng(center.lat, center.lng),
      level,
    }); //지도 생성 및 객체 리턴
  },
  watch: {
    "options.level"(cur, prev) {
      console.log(`[LEVEL CHANGED] ${prev} => ${cur}`);
      this.mapInstance.setLevel(cur);
    },
    "options.center"(cur, prev) {
      console.log(`[NEW CENTER]`, cur.lat, cur.lng);
      this.mapInstance.setCenter(new kakao.maps.LatLng(cur.lat, cur.lng));
    },
  },
};
</script>

<style>
.kmap {
  height: 600px;
}
</style>




api.js
const api = {
  harbor: {
    all(callback) {
      const harbors = [
        {
          seq: 398,
          place: "제주항 국제 여객 터미널",
          lat: 33.52456237850086,
          lng: 126.54371888191963,
        },
        {
          seq: 399,
          place: "통영항",
          lat: 34.83952733985843,
          lng: 128.42015935198992,
        },
        {
          seq: 400,
          place: "부산 국제 크루즈 터미널",
          lat: 35.07980714092641,
          lng: 129.0798233676466,
        },
      ];
      callback({ success: true, harbors });
    },
  },
};

export default api;








마치며

vue 를 공부하면서 api 도 활용할 수 있는 방법으로 공부해보면 좋겠다싶었고, 그 중에서도 한 번도 사용해보지 않았던 지도를 활용하는 방법을 배운다는 생각에 들뜨기도 한다. 다만 지도를 활용할 수 있는 방안도 많고, 그간과는 조금 다르게 option api 를 이용해서 작성하는 터라 어렵게 느껴지기도 했다. 그치만 공식 문서와 유튜브를 통해 하나씩 야금야금 따라하고 정리하다보면 내 것으로 만들 수 있을 것이라 생각한다.









0개의 댓글