[Vue + Express + MySQL 웹 사이트 만들기 (3) ] 검색결과 클릭 이벤트로 커스텀 오버레이 및 필터기능 구현

yojeongjin·2022년 9월 22일
0

지금 와서 생각해보면 단순하게 생각했으면 될것을 혼자 문제를 꼬고 꼬고 또 꼬꼬 꼬아서 커스텀 오버레이 부분만 이틀을 붙잡고있었다 ㅠ 바버 ..

찾고싶은 지역의 이름이나 키워드를 입력하면 검색결과 목록에 맛집 목록이 출력되고 그 목록들 중 한가지를 클릭하면 지도에 커스텀 오버레이가 나타나는 기능을 만들 계획이였다.

문제는 이벤트가 입력되는 컴포넌트와 결과가 출력되는 컴포넌트가 다르다는 점이였다.

검색 결과 목록 -> sidebar 컴포넌트
지도 출력 -> map 컴포넌트

그래서 처음엔 commit으로 mutation을 불러와 선택된 데이터를 변경하고 다시 그 변경값을 지도에서 사용하려고했는데..

여기서 또 발생하는 문제는 사용자가 목록들 중 어떤 데이터를 클릭했느냐 였다.

문제를 해결한 지금에야 index 받아와서 넘겨주면되지 하는데 어제밤에는 이 부분도 생각이 안났고 ,, 덕분에 이래저래 vuex와 mutation, getters, emitt 등등 싹 복습하는 시간이 되었다.


🍋 검색결과 클릭 이벤트

<Sidebar.vue>

<template>
	//...
<ul v-for="data in datas" :key="data.id" class="place" @click="clickInfo">
  	<div>
  		<li class="name">{{ data.place_name }}</li>
		<li class="address">{{ data.address_name }}</li>
	</div>
</ul>
	//...

<script>
    //...      
clickInfo() {
  const placeInfo = document.querySelectorAll('ul > div')

  placeInfo.forEach((li,index) => {
    li.onclick = () => {
      this.emitter.emit('info', index)
    }
  })
}
	//...
          

store에서 받아온 변형된 data값을 출력해주는 부분에 click이벤트를 달고
index를 받아와 eventbus를 이용하여 map component로 넘겨주었다

ul의 li index값을 그대로 받으려했더니 li요소가 두개여서 (음식점 상호명과 주소) 그 부분을 div로 한번 감쌌다.

<Map.Vue>

	//...
computed: {
    datas() {
      return this.$store.state.place.datas
    },
    //...
methods: {
 	//...
  onReceive(i) {
    let position = new kakao.maps.LatLng(this.datas[i].y, this.datas[i].x)

    let customOverlay = new kakao.maps.CustomOverlay({
      position,
      xAnchor: 0.5,
      yAnchor: 1.05,
    });

    let content = `<div class="info-content">${this.datas[i].place_name}</div>`
    customOverlay.setContent(content)
    customOverlay.setMap(this.map)

    let bounds = new kakao.maps.LatLngBounds()
    bounds.extend(position)
  },
}
  //...

datas를 이전에도 받아오고 있었기때문에 받은 index값만 다시 출력해주었다.

💡계산된 데이터 (Computed data)로 선언해주는 이유는 모듈 안의 상태는 빈 데이터이고, 이 데이터가 실제로 action이 동작을해서 정보를 가지고있는 새로운 데이터로 갱신이 되면 반응성이 유지된 상태로 component에서 활용이 되어야하기 때문에 계산된 데이터에 작성해서 사용한다.

커스텀오버레이 디자인 수정해야하는데..
너무 지쳐서 일단 출력이 잘되는데에 의의를 두고있다 🥲


🍋 필터 기능

select 창에 검색 필터를 누르면 원하는 정보만 필터링 되는 기능을 구현했다.

<template>
  //...
<div class="selects">검색결과
	<div 
		@click="filterSelect" 
		v-for="filter in filters" 
        :key="filter.id" 	
		id="filter.id" 
		class="select"> 
          {{ filter.type }}</div>
</div>
  //...

<script>

 //...           
methods: {
  
  filterSelect(e) {
    let type = e.target.outerText
    this.$store.dispatch('place/searchPlaces', {keyword: this.keyword + '맛집' + `'${type}'`})
      }

v-for를 이용해서 필터링 되고있던 영역에 click 이벤트를 달고 outerText를 얻어와서 payload로 같이 넘겨주었다.

✨ 성공적으로 필터링 되었다!


삽질 그만하고싶다😐..
삽질에 기가 빼앗겨서 다른 자잘한 부분들을 다 구현 못했다 ㅠㅠ
특히 ui 부분은 거의 손도 못댐

디자인 부분은 토요일이나 일요일쯤에 한번 싹 뒤엎어야겠다
일단은 기능 구현에 더 중점을 두자!


⏱내일 할 일
✔️ mysql을 이용하여 사용자가 원하는 맛집 저장하고 불러오는 기능 구현

profile
IT is my race🐢

0개의 댓글