반응형
벽돌처럼 차곡차곡쌓아진
디자인을 masonry 라고 이야기한다. 이번엔 사이즈가 제각각 다른 이미지를 활용해 이런 피드리스트를 구현해보았다. 추가로 스크롤링시 다음 페이지를 호출하는 방식을 사용했다. (infinite scroll)
masonry 만 사용한 경우
발생되는 문제점이 애초에 해당 프로젝트는 pull-refresh 를 사용하고 있어서 제대로 영역을 감지 못하는 상태였다. 게다가 데이터 내부에 이미지를 받아오자마자 뿌려주다보니 이미지가 완전히 load 되기 전에 레이아웃이 실행되어 높이 영역이 계속해서 겹치는 현상이 발생했다. 그럼 어떻게 해결할 수 있을까? 라는 생각을 이것저것 해보다가 이미지가 완전히 load 되어 높이가 지정되었을 때, 적용하면 문제없이 구현이 가능할것이라고 생각했다.
사용 라이브러리
👉 masonry
👉 vue-image-loaded
리액트나 다른 구성이면 맞춰서 사용하면 된다
👉 패키지 설치
npm install masonry-layout
npm install vue-images-loaded
👉 index.vue
import Masonry from "masonry-layout";
import ImagesLoaded from "imagesloaded";
👉 html or template
<div id="grid">
<div class="box" v-for="(item, index) in boxItem" :key="index">
<img :src="item.src" />
</div>
</div>
👉 script
data(){
return {
boxItem: [],
page: 1,
}
},
mounted(){
this.getData(); // 초기 데이터 호출
window.addEventListener("scroll", this.handler); // 스크롤 시 호출
},
methods:{
getData(){
axios.get('url',params).then((data)=>{
// boxItem에 담을 요소를 넣어준다
this.boxItem = [...this.boxItem, ...data.arr ];
// boxItem 기준으로 grid 생성
this.$nextTick(() => { this.createGrid();}
this.timeLoading = false;
this.bottomLoading = false;
})
},
createGrid() {
if (!this.boxItem.length > 0) return;
this.$nextTick(() => {
this.imagesLoaded();
});
},
imagesLoaded() {
const grid = document.querySelector("#grid");
return new ImagesLoaded(grid, () => {
this.$nextTick(() => {
// 이미지 로드 후 masonry 호출
this.masonry();
});
});
},
masonry() {
const grid = document.querySelector("#grid");
new Masonry(grid, {
percentPosition: true,
itemSelector: ".box",
});
},
async handler() {
if (this.timeLoading === false) {
this.scroll = window.scrollY;
const SCROLLED_HEIGHT = window.scrollY;
const WINDOW_HEIGHT = window.innerHeight;
const DOC_TOTAL_HEIGHT = document.body.offsetHeight;
const IS_BOTTOM =
WINDOW_HEIGHT + SCROLLED_HEIGHT + 4000 >= DOC_TOTAL_HEIGHT;
// 분기 조건 :: 호출중, 마지막 페이지가 아닌경우
if (
IS_BOTTOM &&
this.lastPage === false && // 마지막 페이지 체크
this.timeLoading === false // axios 호출 상태 체크
) {
this.timeLoading = true;
setTimeout(() => {
if (!this.lastPage) {
let page = this.page + 1;
this.page = page;
this.getData(); // axios 호출
}
}, 700);
}
}
},
}
반응형
'쬬는 개발중' 카테고리의 다른 글
[Vue Error] npm run serve 오류 vue-cli-service: command not found (0) | 2023.06.24 |
---|---|
[javascript] 모바일 검색창 숨기기 기능 구현 (터치 떨림 보정) (1) | 2023.01.30 |
[axios] 엑셀 파일 다운로드 기능 구현하기 (0) | 2022.12.04 |
[axios] 이미지 POST 기능이 제대로 동작하지 않을때 확인사항 (0) | 2022.12.02 |
[javascript | Vue] 이미지 다운로드 기능 만들기 (canvas/url활용) (0) | 2022.12.02 |