[Vue.js] 이미지 슬라이드 라이브러리 없이 구현

정혜인·2023년 10월 10일
0

vue

목록 보기
3/5

이미지 슬라이드를 구현해야 하는데, 버튼이 이미지이기도 하고 여러 슬라이드 기능이 필요해서 라이브러리를 쓰려고 시도했다가 그냥 직접 만들기로 했다.
확실히 react에 비해서 vue의 라이브러리가 적고, 활용성이 낮다는 것을 느꼈다. 그래도 슬라이더 구현에 생각보다 시간을 쏟지 않아서 괜찮았던 것 같다.


이미지 하나씩의 슬라이드가 아니라, 이전 페이지에서 선택한 이미지들 중 4개씩 슬라이드 되는 기능을 구현해야 했기 때문에 조금은 복잡했던 것 같다.
특히 이미지의 개수도 정해져있지 않았기 때문에 길이를 css로 지정할 수 없어 조금 복잡해졌다.


// 페이지별 이미지 배열 새로 만들기
		const getPageImages = (pages: number) => {
			currentPage.value = pages;
			const start = (pages - 1) * itemsPerPage.value;
			const end = start + itemsPerPage.value;
			callChild();
			newArr.value = imgArr.value.slice(start, end);
         
          //첫번째 페이지 (왼쪽에 페이지가 없는 경우)
			if (currentPage.value != 1) {
				prevArr.value = imgArr.value.slice(start - itemsPerPage.value, end - itemsPerPage.value);
			} else if (currentPage.value === 1) {
				prevArr.value = [];
			}
			//마지막 페이지 (오른쪽에 페이지가 없는 경우)
			if (currentPage.value != totalPageCount.value) {
				nextArr.value = imgArr.value.slice(start + itemsPerPage.value, end + itemsPerPage.value);
			} else if (currentPage.value === totalPageCount.value) {
				nextArr.value = [];
			}
			return newArr;
		};

// 왼쪽 화살표
const prevPage = () => {...}

...
 <Component
  :currentPage="currentPage"
  :totalPage="totalPageCount"
  :images="newArr"
  :prevImages="prevArr"
  :nextImages="nextArr"
...
                        />

//component 파일


// 슬라이드 시작
const startDrag = (event: any) => {
  isDragging.value = true;
  // 시작점
  startX.value = event.changedTouches[0].clientX;
		};
// 슬라이드중일때
const handleDrag = (event: any) => {
  isDragging.value = true;

  if (isDragging.value) {
    // 현재 x좌표
    currentX.value = event.changedTouches[0].clientX;

    // 오른쪽으로 움직였을때
    if (currentX.value - startX.value < 0) {
      isNextPage.value = true;
    }
    // 왼쪽으로 움직였을때
    else if (currentX.value - startX.value > 0) {
      isPrevPage.value = true;
    }

    const element: any = document.querySelector('.choose-grid-box');
    element.style.left = '0px';
    element.style.transform = 'translate(' + (currentX.value - startX.value) + 'px, -50%)';
  }
};

// 슬라이드 끝
const endDrag = (event: any) => {
  const element: any = document.querySelector('.choose-grid-box');
  element.style.left = '';
  element.style.transform = '';
  if (isNextPage.value) {
    if (props.currentPage < props.totalPage) {
      emit('nextPage');
    }

    isNextPage.value = false;
  } else if (isPrevPage.value) {
    if (props.currentPage > 1) {
      emit('prevPage');
    }
    isPrevPage.value = false;
  }
  isDragging.value = false;
};


<div class="choose-grid-box" @touchstart="startDrag" @touchmove="handleDrag" @touchend="endDrag">
  <div class="prev-choose-grid-box">
    ---
  </div>
  <div class="choose-item" v-for="(image, index) in images" :key="index" ...>
    ...
  </div>
  <div class="next-choose-grid-box">
    ---
  </div>
</div>
// scss 파일 
.prev-choose-grid-box {
    left: -350px;
    ...
}
.choose-grid-box {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    transform-origin: center;
    ...
}
.next-choose-grid-box {
    left: 350px;
    ...
}

이렇게 작성해주었다.
마우스의 현재 X 값을 기준으로 처음 클릭한 X 값과 비교하여 왼쪽/오른쪽을 감지하고, 그에 따라 페이지를 넘겨준다.

그런데 그냥만 하면 왼/오른쪽에 각각 요소들 없이 현재 페이지만 슬라이드 되므로, 위처럼 prev-choose-grid-box와 next-choose-grid-box 처럼 이전, 이후 컴포넌트들을 각각 추가해주면 자연스러운 슬라이드 기능을 구현할 수 있게 된다.

0개의 댓글