Intersection observer는 기본적으로 브라우저 뷰포트(Viewport)와 설정한 요소(Element)의 교차점을 관찰하며, 요소가 뷰포트에 포함되는지 포함되지 않는지, 더 쉽게는 사용자 화면에 지금 보이는 요소인지 아닌지를 구별하는 기능을 제공한다.
const io = new IntersectionObserver(callback, options) // 관찰자 초기화
io.observe(element) // 관찰할 대상(요소) 등록
<div ref="observer">Loading...</div>
기능을 동작하게 하기 위해서 그 기능을 어디에 등록해야하는지가 중요한데 그때 필요한게 라이프사이클이다.
우리는 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
라고 입력해준다.const App = {
data() {
return {
title: '',
page: 1,
// 내가 가져와야할 영화의 총 개수 totalResults, 초기값 0에서 출발
total: 0,
movies: [],
// 화면 깜빡이게 하기
showObserver: true,
};
},
computed: {
// 더 가져와야할 영화 갯수가 있는지 확인
hasTheRest() {
return this.total > this.movies.length;
},
},
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속성을 이용하면 뷰가 알아서 찾아주는 것도 간편한 것 같다!