AdBanner.vue 구성 요소
- 광고 배너: 광고 이미지를 보여주는 주요 영역.
- 광고를 넘겨주는 화살표: 광고를 전환할 수 있는 화살표 버튼.
- 인디케이터: 현재 표시 중인 광고의 인덱스를 나타내며, 클릭 시 해당 광고로 이동하는 기능을 제공.
개발 순서
- HTML 템플릿 구성
- CSS 스타일링
- JavaScript 기능 구현
1. AdBanner.vue 템플릿 초기 구성
구성 요소
- 광고 배너 영역: <div class="ad_space"> 내부에 광고 이미지가 표시됨.
- 화살표 영역: 좌우 화살표로 광고를 넘길 수 있는 기능을 제공.
- 인디케이터 영역: 광고의 현재 인덱스를 시각적으로 표시하고, 특정 광고로 이동할 수 있도록 함.
<template>
<div class="ad_container">
<div class="ad_space">
<!-- 광고 이미지가 들어가는 공간 -->
</div>
<!-- 화살표 부분 -->
<div class="arrow ad_left_arrow">
◀
</div>
<div class="arrow ad_right_arrow">
▶
</div>
<!-- 인디케이터 부분 -->
<div class="ad_indicators">
<!-- 인디케이터가 들어가는 공간 -->
</div>
</div>
</template>
- 설명
- 광고, 화살표, 인디케이터: 광고를 표시하는 공간, 광고를 전환하는 화살표, 현재 광고의 위치를 표시하는 인디케이터로 구성됨.
- 위치와 모양: CSS 스타일로 조정 예정.
- 기능: JavaScript로 구현 예정.
2. AdBanner.vue 스타일 구성
2-1. 컴포넌트 레이아웃 설정
.ad_container: 컴포넌트의 전체 레이아웃을 설정하는 컨테이너.
.ad_container{
position:relative;
overflow:hidden;
width:100%;
height: 350px;
background-color: #f1f1f1;
}
- position: relative: 자식 요소들의 위치를 제어할 기준점을 제공.
- overflow: hidden: 컨테이너를 넘어가는 자식 요소의 콘텐츠를 숨김.
2-2. 자식 요소 스타일 설정
.ad_space: 광고 이미지를 표시하는 공간.
.ad_space{
height:100%;
}
- 광고 이미지를 표시하는 공간. height: 100%로 설정하여 부모 요소의 전체 높이를 사용.
.arrow: 광고 전환을 위한 화살표 스타일.
.arrow {
position: absolute;
top: 50%;
transform:translateY(-50%);
font-size: 80px;
color: black;
background-color: rgba(255, 255, 255, 0.8);
cursor: pointer;
user-select: none;
z-index: 2;
}
- position: absolute
- 부모요소를 기준으로 절대적인 위치에 배치
- top:50%
- 부모요소를 기준으로 위에서부터 50% 위치에서 해당 요소의 위치가 시작함
- transform:traslateY(-50%);
- 해당 요소의 위치를 지정값만큼 Y축(세로)로 이동시킴
- -50%이기 때문에 요소의 크기 절반만큼 위로 올라가고, +50%이면 요소의 크기 절반만큼 아래로 올림
- top:50%와 같이 사용함으로써 해당요소가 전체 레이아웃에 정중앙에 위치할수 있게 함.
- 해당 요소의 위치를 지정값만큼 Y축(세로)로 이동시킴
- color: black:
- 화살표의 가시성을 높이기 위해 검정색으로 설정.
- background-color: rgba(255, 255, 255, 0.8):
- 화살표의 범위를 시각적으로 구분하기 위해 반투명한 흰색 배경색 설정.
- cursor: pointer:
- 화살표 위에 마우스를 올릴 때 커서 모양이 포인터로 변경되도록 설정하여 클릭 가능성을 시각적으로 표시.
- user-select: none: 사용자가 요소의 텍스트를 선택하지 못하도록 설정하여 불필요한 텍스트 선택 방지.
- z-index: 2: 요소의 쌓임 순서를 설정하여 다른 요소들 위에 표시되도록 보장.
.ad_left_arrow, .ad_right_arrow
.ad_left_arrow{
left:10px;
}
.ad_right_arrow{
right: 10px;
}
화살표가 배너의 가장자리에 딱 붙지 않고, 약간의 여백을 두어 시각적 여유를 제공하기 위함
.ad_indicators, ad_indicator_span
.ad_indicators{
position: absolute;
bottom:10px;
right:10px;
display:flex;
gap: 5px;
}
.ad_indicator_span{
display:block;
width:10px;
height:10px;
background-color:#ccc;
border-radius:50%;
cursor:pointer;
}
.
- ad_indicators: 인디케이터가 배치될 공간.
- .ad_indicator_span: 각 인디케이터의 스타일. 크기, 배경색, 모양을 설정.
아주 작고 간단한 스타일로 사용될 때는 span이 더 적합하다고 하여 사용
3. 기능 구현
3-1. 마우스 오버 시 화살표 표시 기능
▶ 해당 이벤트가 발동할 요소에 이벤트 핸들러 삽입
<div class="ad_container" @mouseover="" @mouseleave="">
- 가장 상위 요소에 작성
▶ 상태를 저장할 변수 생성
showArrow 변수를 data에 추가하여 화살표 표시 여부를 제어.
false일 경우 화살표가 보이지 않으며, true일 경우 화살표가 표시됨.
<script>
export default {
data() {
return {
showArrow:false,
}
}
}
</script>
▶ 조건부 렌더링 적용
v-if를 사용하여 showArrow 값에 따라 화살표를 표시하거나 숨김.
<div class="arrow ad_left_arrow" v-if="showArrow == true">
◀
</div>
<div class="arrow ad_right_arrow" v-if="showArrow == true">
▶
</div>
▶ 화살표 표시 상태 변경 함수 구현
마우스 이벤트에 반응하여 showArrow 값을 변경하는 함수를 작성.
<script>
export default {
data() {
return {
showArrow:false,
}
},
methods:{
turnOnArrow(){
this.showArrow = true;
},
turnOffArrow(){
this.showArrow = false;
}
}
}
▶ 템플릿에서 이벤트 핸들러 연결
화살표 기능 구현 완료 후, 이벤트 핸들러를 템플릿에 연결하여 기능 완성.
<template>
<div class="ad_container" @mouseover="turnOnArrow()" @mouseleave="turnOffArrow()">
<div class="ad_space">
<div class="ad-item">
</div>
</div>
<!-- 화살표 부분, 특수문자 사용 -->
<div class="arrow ad_left_arrow" v-if="showArrow == true">
◀
</div>
<div class="arrow ad_right_arrow" v-if="showArrow == true">
▶
</div>
<!--인디케이터 부분 -->
<div class="ad_indicators">
<span class="ad_indicator_span">
</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showArrow:false,
}
},
methods:{
turnOnArrow(){
this.showArrow = true;
},
turnOffArrow(){
this.showArrow = false;
}
}
}
</script>
2. 광고를 보여줄 기능 구현
▶ 광고 이미지 배열 생성 및 사용
Ads 배열에 광고 이미지 경로를 저장하고, 해당 배열을 사용하여 광고를 동적으로 표시.
템플릿 부분
<div class="ad_space">
<img :src="Ads[currentIndex]" alt="광고 이미지" class="ad-item" />
</div>
스크립트 부분
export default {
data() {
return {
showArrow: false,
Ads: [
require('@/assets/img/ad/MenuMateAd1.png'),
require('@/assets/img/ad/MenuMateAd2.png')
],
currentIndex: 0,
}
},
- 광고 이미지 배열 생성: Ads 배열에 광고 이미지 경로를 저장.
- img 태그 사용: 광고 이미지를 표시하기 위해 <img> 태그 삽입.
- 속성 바인딩 사용: :src를 통해 Ads 배열의 현재 인덱스 이미지 경로 동적 설정.
- :src 는 v-bind:src 의 축약
- 인덱스 제어: currentIndex 변수를 사용하여 현재 표시할 광고 이미지 관리.
img 태그를 넣으면서 스타일을 ad_item 스타일을 추가함
.ad-item {
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
}
3. 화살표를 눌렀을 때 광고 전환 기능 구현
▶ 화살표 클릭 이벤트 구현
화살표를 클릭하면 광고 배열의 다음 인덱스로 넘어가거나 이전 인덱스로 돌아가도록 설정.
<div class="arrow ad_left_arrow" v-if="showArrow == true" @click="">
◀
</div>
<div class="arrow ad_right_arrow" v-if="showArrow == true" @click="">
▶
</div>
▶ 인덱스 변경 메서드 구현
화살표 클릭 시 currentIndex를 변경하는 메서드를 작성.
methods: {
turnOnArrow() {
this.showArrow = true;
},
turnOffArrow() {
this.showArrow = false;
},
nextAds(){
this.currentIndex=(this.currentIndex+1)%this.Ads.length;
},
prevAds(){
this.currentIndex=(this.currentIndex+this.Ads.length-1)%this.Ads.length;
}
}
▶ 설명:
- 순환 방식: nextAds와 prevAds 메서드를 사용하여 마지막 광고에서 첫 광고로 돌아가거나, 첫 광고에서 마지막 광고로 돌아가는 순환 방식 구현.
4. 인디케이터 기능 구현
▶ 광고 개수만큼 인디케이터 생성
v-for 반복문을 사용하여 광고 개수만큼 인디케이터 생성.
<span class="ad_indicator_span" v-for="(ad,index) in Ads" :key="ad">
단, 이렇게만 하면 index라는 변수를 사용하지 않아 오류가 발생함, 사실 :key="index" 를 사용하면 오류발생하지 않고 해당 v-for를 사용할 수 있고, 자주 그렇게 사용하는 것 같지만 내가 본 강의에서는 :key 에서 index를 사용하는 걸 지양하라고 배움 why?
key 사용 지침: :key="index" 사용을 지양하는 이유는 배열의 끝이 아닌 다른 위치에 새 항목이 삽입될 경우, Vue가 DOM 패치 시 새 항목 데이터를 정확하게 인식하지 못하고, 로컬 데이터가 함께 업데이트되지 않기 때문.
methods: {
turnOnArrow() {
this.showArrow = true;
},
turnOffArrow() {
this.showArrow = false;
},
nextAds(){
this.currentIndex=(this.currentIndex+1)%this.Ads.length;
},
prevAds(){
this.currentIndex=(this.currentIndex+this.Ads.length-1)%this.Ads.length;
},
// 인디케이터 클릭시 해당 인덱스의 광고보여주는 기능
setCurrentIndex(index){
this.currentIndex=index;
},
}
▶ 인디케이터 클릭 시 해당 광고로 이동 기능
인디케이터를 클릭하면 해당 인덱스의 광고로 이동하는 기능 추가.
<span class="ad_indicator_span" v-for="(ad,index) in Ads" :key="ad" @click="setCurrentIndex(index)">
▶ 현재 보고 있는 인디케이터 색상 표시 기능
현재 광고의 인디케이터 색상을 표시하는 기능 구현.
<div class="ad_indicators">
<span :class="{ 'ad_indicator_span': true, 'active': index === currentIndex }" v-for="(ad,index) in Ads" :key="ad" @click="setCurrentIndex(index)">
</span>
</div>
▶ 설명:
- 동적 클래스 바인딩 사용: :class를 사용하여 두 개 이상의 클래스를 동적으로 바인딩. 객체(Object) 문법과 배열(Array) 문법 두 가지 방법을 사용할 수 있음.
- 객체 문법: :class="{ 'class-name': 조건, 'class-name': 조건 }" 형태로, 조건이 true일 때 클래스가 적용됨.
- 배열 문법: :class="['class-name', { 'class-name': 조건 }]" 형태로, 기본 클래스와 조건부 클래스를 함께 사용.
active 속성 스타일 추가
.active{
background-color: crimson;
}
5. 광고 자동 넘기기 기능 구현
자동으로 광고를 넘기는 기능을 구현하기 위해 JavaScript의 setInterval과 clearInterval 함수를 사용할 예정
setInterval:
- 이 함수는 일정한 밀리초(ms) 간격으로 동일한 동작(함수)을 반복해서 실행하도록 설정할 때 사용
setInterval(callbackFunction, delay);
- callbackFunction: 반복적으로 실행할 함수.
- delay: 함수를 반복 실행할 시간 간격(밀리초 단위).
clearInterval:
- setInterval로 설정된 반복 작업을 중지하고 싶을 때 사용
clearInterval(intervalId);
1. Interval의 ID를 저장할 변수를 추가
export default {
data() {
return {
showArrow: false,
Ads: [
require('@/assets/img/ad/MenuMateAd1.png'),
require('@/assets/img/ad/MenuMateAd2.png'),
],
currentIndex: 0,
AutoSlideInterval: null,
}
}
- 컴포넌트의 data 속성에 Interval ID를 저장할 변수를 추가
2. Methods에 setInterval을 실행시킬 함수 추가
methods: {
turnOnArrow() {
this.showArrow = true;
},
turnOffArrow() {
this.showArrow = false;
},
nextAds() {
this.currentIndex = (this.currentIndex + 1) % this.Ads.length;
},
prevAds() {
this.currentIndex = (this.currentIndex + this.Ads.length - 1) % this.Ads.length;
},
// 인디케이터 클릭시 해당 인덱스의 광고보여주는 기능
setCurrentIndex(index) {
this.currentIndex = index;
},
// Interval 시작 함수
StartAutoSlideAd() {
this.AutoSlideInterval = setInterval(() => {
this.nextAds();
},2500);
},
}
3. 컴포넌트가 마운트될 때 Interval이 시작되도록 mounted 라이프사이클 훅에 함수 추가
mounted(){
this.StartAutoSlideAd();
},
컴포넌트가 마운트될 때(mounted) 자동으로 광고가 슬라이드되도록 StartAutoSlideAd 메서드를 호출
4. Interval 종료하는 함수 method의 추가
methods: {
turnOnArrow() {
this.showArrow = true;
},
turnOffArrow() {
this.showArrow = false;
},
nextAds() {
this.currentIndex = (this.currentIndex + 1) % this.Ads.length;
},
prevAds() {
this.currentIndex = (this.currentIndex + this.Ads.length - 1) % this.Ads.length;
},
// 인디케이터 클릭시 해당 인덱스의 광고보여주는 기능
setCurrentIndex(index) {
this.currentIndex = index;
},
// Interval 시작 함수
StartAutoSlideAd() {
this.AutoSlideInterval = setInterval(() => {
this.nextAds();
},2500);
},
//Interval 종료함수
EndAutoSlideAd(){
clearInterval(this.AutoSlideInterval);\
this.AutoSlideInterval = null;
}
}
5. 해다 컴포넌트가 unmount 될때 Interval 끄기
unmounted(){
this.EndAutoSlideAd();
}
컴포넌트가 언마운트될 때 EndAutoSlideAd를 호출하여 자동 슬라이드를 중지하고, 메모리 누수를 방지
6. 광고위에 마우스 올려놓으면 Interval 껐다가 다시 마우스가 떠나면 다시 실행 기능 구현
기존에 만들어놓았던 마우스오버 마우스리브 이벤트 핸들러에 각각 인터벌종료함수와 인터벌시작함수를 추가시킴
methods: {
turnOnArrow() {
this.EndAutoSlideAd();
this.showArrow = true;
},
turnOffArrow() {
this.StartAutoSlideAd();
this.showArrow = false;
},
nextAds() {
this.currentIndex = (this.currentIndex + 1) % this.Ads.length;
},
prevAds() {
this.currentIndex = (this.currentIndex + this.Ads.length - 1) % this.Ads.length;
},
// 인디케이터 클릭시 해당 인덱스의 광고보여주는 기능
setCurrentIndex(index) {
this.currentIndex = index;
},
// Interval 시작 함수
StartAutoSlideAd() {
this.AutoSlideInterval = setInterval(() => {
this.nextAds();
},2500);
},
//Interval 종료함수
EndAutoSlideAd(){
clearInterval(this.AutoSlideInterval);
this.AutoSlideInterval = null;
}
}
'프로젝트 진행 기록 > 메뉴 메이트 웹 애플리케이션 개발' 카테고리의 다른 글
| SignupPage.vue 구성 (0) | 2024.09.12 |
|---|---|
| LoginPage.vue 화면 구성 (0) | 2024.09.07 |
| StartMenuMate.vue 파일 정리 (0) | 2024.08.29 |
| MainPage.vue 관련 정리 (0) | 2024.08.26 |
| App.vue 파일 정리 (0) | 2024.08.26 |