[TIL # 27] Vue 2일차

Yejin Yang·2022년 5월 17일
0

[TIL]

목록 보기
27/67
post-thumbnail

IntersectionObserver

Intersection observer는 기본적으로 브라우저 뷰포트(Viewport)와 설정한 요소(Element)의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 포함되지 않는지, 더 쉽게는 사용자 화면에 지금 보이는 요소인지 아닌지를 구별하는 기능을 제공한다.

문법

const io = new IntersectionObserver(callback, options) // 관찰자 초기화
io.observe(element) // 관찰할 대상(요소) 등록
  • new IntersectionObserver()를 통해 생성한 인스턴스(io)로 관찰자(Observer)를 초기화하고 관찰할 대상(Element)을 지정한다.
  • 관찰할 대상(Target)이 등록되거나 가시성(Visibility, 보이는지 보이지 않는지)에 변화가 생기면 관찰자는 콜백(Callback)을 실행한다.
  • 생성자는 2개의 인수(callback, options)를 가진다.

Vue 이용하기

HTML

<div ref="observer">Loading...</div>
  • vue의 ref 속성을 이용하여 참조할 데이터 명을 입력
  • HTML에 ref 속성을 사용한다면 흔히 Document.querySelector() 를 사용하지 않아도 된다.

라이프사이클 다이어그램



기능을 동작하게 하기 위해서 그 기능을 어디에 등록해야하는지가 중요한데 그때 필요한게 라이프사이클이다.

우리는 created 또는 mounted를 쓰면 된다.(파란 네모 박스로 체크해둔 부분)
통상 created를 먼저 고려해서 쓰면 된다. 그런데 에러가 뜬다? -> mounted로 바꿔준다. 보라색 네모박스로 체크해둔 부분이 HTML을 만나는 순간이다.
만약 created를 사용해서 에러가 떴다면 HTML과 만나기 전이여서 그렇다. HTML을 만난 다음에 실행하는 라이프스타일은 mounted이다.

mounted를 사용해서 HTML구조에 대해서 알게해주면 된다.

관찰 대상 지정하기

mounted() {
    const io = new IntersectionObserver((entries) => {
      // 화면에 들어오니 안들어오니 여부를 이부분에서 알 수 있음
      entries.forEach((entry) => {
      // true인 경우 화면에 들어왔다는 것
        if (entry.isIntersecting) {
      // 10개 더 가져오세요
          this.searchMovies()
        }
      });
    });
    io.observe(this.$refs.observer);
  },

io.observe(this.$refs.observer)

  • this를 사용해서 요소에 접근한다.
  • ref 속성은 $refs 라고 입력해준다.

계산된 데이터 생성(computed)

const App = {
  data() {
    return {
      title: '',
      page: 1,
      // 내가 가져와야할 영화의 총 개수 totalResults, 초기값 0에서 출발
      total: 0,
      movies: [],
      // 화면 깜빡이게 하기 
      showObserver: true,
    };
  },
  computed: {
    // 더 가져와야할 영화 갯수가 있는지 확인
    hasTheRest() {
      return this.total > this.movies.length;
    },
  },
  • 최초 검색하면 10개의 영화 데이터가 처음으로 들어온다 그럼 this.movies.length 에는 10개의 아이템이 생긴다. total수가 20개라면 더 가져올 수 있다.
  • computed 는 한번만 계산하지 않는다. 값이 바뀌면 연산을 알아서 한번 더 한다.
  • 서치 버튼을 누르기 전에는 0 > 0, 즉 false에서 한번 더 계산해서 갱신한다.
  • 결과 값을 return 시킨다.(getter)

    methods:

    methods: {
      // 최초 요청 함수(10개)
       async searchMovies(isFirst) {
         if (isFirst) {
      // 최초 검색이라면 movies를 빈배열로 초기화
           this.movies = [];
      // 최초 검색이라면 page를 1로 초기화
           this.page = 1;
         }
         let res = await fetch(
           `https://www.omdbapi.com?apikey=${API_KEY}&s=${this.title}&page=${this.page}`
         );
         res = await res.json();
         console.log(res);
         const { Search, totalResults } = res;
         this.movies.push(...Search);
         this.page += 1;
     // totalResults는 문자 데이터여서 숫자로 변환
         this.total = Number(totalResults);
     // 화면 깜빡이게 하기
         this.showObserver = false;
         setTimeout(() => {
           this.showObserver = true;
         });
       },
     },
    };
    Vue.createApp(App).mount('#app');
// 에러
<div v-if="hasTheRest && showObserver" ref="observer">Loading...</div>

// 정상
<div v-show="hasTheRest && showObserver" ref="observer">Loading...</div>

v-if는 등록한 반응형 데이터에따라 화면에 그리거나 아예 안그린다.
그런데 v-show는 무조건 한번은 랜더링 한다. 랜더링은 되어있지만 display: none을 걸어서 화면에만 안보이는 상태로 만든다.


회고

뷰의 여러 속성에 대해서 실습을 통해 배우니까 더욱 와닿았다. 공부한 일부분만 적어서 본문에 나와있진 않지만 클래스 바인딩, 스타일 바인딩 기술이 신기했다. ref속성을 이용하면 뷰가 알아서 찾아주는 것도 간편한 것 같다!

profile
Frontend developer

0개의 댓글