201124 TIL Fade-image-slider 만들기

ToastEggsToast·2020년 11월 24일
0

Vue

목록 보기
4/4
post-thumbnail

Vue Fade-slider Code

라이브러리를 쓰지 않겠다고 열심히 꼬물거리면서 이미지 슬라이더를 만들었다. 실제로는 사용은 못 했다. pagination 작동이 안 되어서... ._.).. 시무룩

Code

<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로 변경시켜준다.

사용한 Vue api

v-for

어떤 데이터를 기반으로 반복시켜서 같은 엘리먼트/컴포넌트를 생성해낼 때 주로 사용한다.
위 코드에서의 경우, 보여줄 이미지를 배경으로 둔 div를 반복해서 생성해내기 위해 사용했다.

v-bind

v-bind는 클래스나 속성, props 등을 동적으로 넘겨줄 때 주로 사용한다.
v-bind:key:key로 줄여서 작성이 가능하고, 특히 v-for를 사용 할 경우 key를 꼭!! 바인딩 시켜줘야한다.

props

부모 컴포넌트에서 자식 컴포넌트에게 어떤 데이터를 넘겨 줄 경우, 그 데이터를 props라고 한다.
props 는 Object, 또는 Array 형태로 내려진다.
Vue에서 props를 사용할 경우, script에서 props를 명시해준 후 사용이 가능하다.

FeedBack / Tip

같이 공부하는 프엔 개발자분이 n이상으로 커질 경우 x로 돌아가게 하는 경우 나머지 연산자를 활용하면 좋아. 라는 팁을 주셨다. 예를 들어

this.currentIndex = this.currentIndex + 1;
  if (this.currentIndex >= this.imageList.length) {
	this.currentIndex = 0;
  }
}

이런 코드를

this.currentIndex = (this.currentIndex + 1) % this.imageList.length

이런 식으로! 나머지 연산자를 사용하는건 전혀 생각도 못 했었는데...
역시 공부를 열심히 해야겠다고 또 다시 다짐하게 되었었다.

profile
개발하는 반숙계란 / 하고싶은 공부를 합니다. 목적은 흥미입니다.

0개의 댓글