10/19

김승우·2020년 10월 19일
0

TIL

목록 보기
30/68

Vue 인프런 강의 복습

Ref : https://www.inflearn.com/course/vuejs/

1. AddCard 바깥 클릭시 닫히는 기능

  • Idea :

    1. AddCard의 마운트 될 때(mounted 훅) window에 이벤트를 바인딩!
    2. 그리고 destroyed훅에서 이벤트를 해제한다.
  • addEventListener & removeEventListener

window.addEventListener('click', clickHandler, false);
window.removeEventListener('click', clickHandler, false);
  • 익명함수를 사용하지 않으면, 이벤트핸들러를 바인딩하고 삭제할때 용이하다.
  • Node.contains(otherNode)
    : 인자로 주어지는 노드가 해당 노드에 포함되어 있는지 여부를 true/false값으로 리턴

  • 코드

//AddCard.vue
//methods
bindEvent() {
	const self = this;
	document.querySelector("body")
	.addEventListener("click", this.onClickOutSide, false);
	},
//1.
onClickOutSide(event) {
	const $target = event.target;
	const $parent = this.$el.closest(".list-item");
	if ( $parent.contains($target) ||
		$target.classList.contains("addCard__toggle")
	   ) {
      return;
    }
    this.$emit("close");
},

//mounted
//2.
document.querySelector("body").addEventListener("click", this.onClickOutSide, false);
  
//destroyed
//3.
document.querySelector("body").removeEventListener("click", this.onClickOutSide, false);
  1. 클릭 시 실행되는 함수, Node.conatins를 활용해, 클릭된 엘리먼트가 "list-item" 엘리먼트에 포함되어 있지 않으면, AddCard 컴포넌트를 닫는다. 이때, "addCard__toggle" 엘리먼트가 클릭되었을 경우도 제외했는데 이유는 2번에서 이어서 설명하겠습니다.
  2. this.$el을 참조하기위해서 컴포넌트가 마운드 된 이후(DOM에 렌더링 된 이후), 클릭 이벤트를 바인딩했습니다. 그런데, 마운트된 순간과 거의 동시에 이벤트가 바인딩되고 실행되어서, $parent.contains($target) === false가 되었고, 바로 컴포넌트가 닫혔습니다. $target === "addCard__toggle"엘리먼트 였고, 따라서 강제로 이 엘리먼트를 제외시켰습니다. ===> 좋은 방법 찾기!
  3. 컴포넌트가 돔에서 제거되면, body에 걸려있는 클릭 이벤트를 제거합니다.

2. Card 컴포넌트

  • Card 컴포넌트는 "중첩 라우팅"을 이용해서 Board.vue의 <router-view></router-view>를 통해서 렌더링되고 있다.
  • Modal 컴포넌트를 통해서 만들었지만, 기존 Modal을 사용한 컴포넌트와 다르게, $emit("close")를 이용하지 않고, <router-link></router-link>를 이용해서 닫기처리를 했다.
  • 코드
<header slot="header" class="cardView__header">
                <span class="cardView__title">{{ card.title }}</span>
                <router-link :to="`/b/${board.id}`" class="cardView__close">
                    &times;
                </router-link>
</header>
<footer slot="footer" class="cardView__footer">
                <b-button
                    variant="dark"
                    class="cardView__button"
                    @click="goBoard"
                    >Ok</b-button
                >
</footer>
goBoard() {
            const bid = this.board.id;
            this.$router.push(`/b/${bid}`);
        },
  • <router-link></router-link>를 통해서 Card 컴포넌트를 닫는다. => 라우팅 경로가 변경되므로, Board.vue 내부의 <router-view></router-view>에 Card컴포넌트가 렌더링되지 않는다.
  • goBoard()라는 메소드를 이용해서 <router-link></router-link>를 이용하지않고, 라우팅을 변경하는 로직을 작성했다.

* Reference

1. Node.contains() : https://developer.mozilla.org/ko/docs/Web/API/Node/contains

2. addEventListener & removeEventListener : https://developer.mozilla.org/ko/docs/Web/API/EventTarget/addEventListener

profile
사람들에게 좋은 경험을 선사하고 싶은 주니어 프론트엔드 개발자

0개의 댓글