라이브러리를 쓰지 않겠다고 열심히 꼬물거리면서 이미지 슬라이더를 만들었다. 실제로는 사용은 못 했다. pagination 작동이 안 되어서... ._.).. 시무룩
<template>
<div class="mainBanner">
<div class="sliderContainer">
<div
v-for="(img, index) in imageList"
:key="img.id"
:style="{
backgroundImage: `url(${img.imgSrc})`,
zIndex: `${
index === currentIndex ? 3 : index === lastIndex ? 2 : 1
}`
}"
:class="{ active: index === currentIndex }"
></div>
</div>
<p>내가 원하는 그곳을 <span>찜</span>하다.</p>
<ul>
<li
v-for="index in imageList.length"
:key="index"
:class="{ active: index === currentIndex + 1 }"
@click="sliderHandler(index - 1)"
></li>
</ul>
</div>
</template>
<script>
export default {
name: "MainBanner",
data: () => {
const imageList = [
{
id: 1,
imgSrc:
"imgUrl1"
},
{
id: 2,
imgSrc:
"imgUrl2"
},
{
id: 3,
imgSrc:
"imgUrl3"
}
];
return {
currentIndex: 0,
lastIndex: imageList.length - 1,
imageList
};
},
methods: {
startRotation() {
this.lastIndex = this.currentIndex;
this.currentIndex = this.currentIndex + 1;
if (this.currentIndex >= this.imageList.length) {
this.currentIndex = 0;
}
},
sliderHandler(idx) {
console.log(idx);
this.activeIndex = idx;
if (idx === 0) {
this.lastIndex = this.imageList.length - 1;
}
if (idx !== 0) {
this.lastIndex = idx - 1;
}
console.log(this.imageList);
console.log(this.activeIndex);
}
},
mounted() {
this.setInterval = setInterval(() => {
this.startRotation();
}, 3000);
},
beforeDestroy() {
clearInterval(this.setInterval);
}
};
</script>
<style scoped lang="scss">
.mainBanner {
.sliderContainer {
position: relative;
div {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100vh;
background-repeat: no-repeat;
background-position: 50% 50%;
background-size: cover;
&.active {
animation-name: activeIndex;
animation-duration: 3s;
animation-fill-mode: forwards;
animation-iteration-count: infinite;
}
}
}
}
</style>
이미지들을 백그라운드로 가지고 있는 div들을 한 곳에 쌓아올려서 z-index로 레이어 위치를 바꿔주는 느낌으로 큰 틀을 잡아두었다.
currentIndex로 가장 위에 위치하게 할 div를 설정하고, lastIndex로 그 밑에 위치하게 할 div를 설정해준다.
AutoPlay를 위해 setInterval로 함수를 반복실행 시켜주고, 컴포넌트를 빠져나갈 경우 즉 페이지에서 나갈 경우 반복되고있는 함수를 종료시킨다.
fade 효과를 위해 currentIndex에 active라는 클래스를 붙여주고,
해당 클래스를 가지게 될 경우 css 애니메이션으로 opacity 0 > opacity 1로 변경시켜준다.
어떤 데이터를 기반으로 반복시켜서 같은 엘리먼트/컴포넌트를 생성해낼 때 주로 사용한다.
위 코드에서의 경우, 보여줄 이미지를 배경으로 둔 div를 반복해서 생성해내기 위해 사용했다.
v-bind는 클래스나 속성, props 등을 동적으로 넘겨줄 때 주로 사용한다.
v-bind:key
는 :key
로 줄여서 작성이 가능하고, 특히 v-for
를 사용 할 경우 key를 꼭!! 바인딩 시켜줘야한다.
부모 컴포넌트에서 자식 컴포넌트에게 어떤 데이터를 넘겨 줄 경우, 그 데이터를 props라고 한다.
props 는 Object, 또는 Array 형태로 내려진다.
Vue에서 props를 사용할 경우, script에서 props를 명시해준 후 사용이 가능하다.
같이 공부하는 프엔 개발자분이 n이상으로 커질 경우 x로 돌아가게 하는 경우 나머지 연산자를 활용하면 좋아.
라는 팁을 주셨다. 예를 들어
this.currentIndex = this.currentIndex + 1;
if (this.currentIndex >= this.imageList.length) {
this.currentIndex = 0;
}
}
이런 코드를
this.currentIndex = (this.currentIndex + 1) % this.imageList.length
이런 식으로! 나머지 연산자를 사용하는건 전혀 생각도 못 했었는데...
역시 공부를 열심히 해야겠다고 또 다시 다짐하게 되었었다.