탭
데모
단순하면 재미가 없으므로 트랜지션을 사용해서 슬라이드하도록 만들었습니다.
사용하고 있는 주요 기능
클래스 데이터 바인딩하기 62페이지
여러 속성 데이터 바인딩하기 64페이지
산출 속성(computed) 120페이지
컴포넌트 146페이지
컴포넌트와 컴포넌트 끼리의 통신 153페이지
트랜지션 194페이지
소스 코드
<template>
<div class="example">
<div class="tabs">
<TabItem
v-for="item in list"
v-bind="item" :key="item.id"
v-model="currentId"/>
</div>
<div class="contents">
<transition>
<section class="item" :key="currentId">
{{ current.content }}
</section>
</transition>
</div>
</div>
</template>
<script>
import TabItem from './TabItem.vue'
export default {
components: { TabItem },
data() {
return {
currentId: 1,
list: [
{ id: 1, label: 'Tab1', content: '콘텐츠1' },
{ id: 2, label: 'Tab2', content: '콘텐츠2' },
{ id: 3, label: 'Tab3', content: '콘텐츠3' }
]
}
},
computed: {
current() {
return this.list.find(el => el.id === this.currentId) || {}
}
}
}
</script>
<style scoped>
.contents {
position: relative;
overflow: hidden;
width: 280px;
border: 2px solid #000;
}
.item {
box-sizing: border-box;
padding: 10px;
width: 100%;
transition: all 0.8s ease;
}
/* 트랜지션 전용 스타일 */
.v-leave-active {
position: absolute;
}
.v-enter {
transform: translateX(-100%);
}
.v-leave-to {
transform: translateX(100%);
}
</style>
<template>
<button @click="$emit('input', id)" :class="[active, 'tab']">
{{ label }}
</button>
</template>
<script>
export default {
props: {
id: Number,
label: String,
value: Number
},
computed: {
active() {
return this.value === this.id ? 'active' : false
}
}
}
</script>
<style scoped>
.tab {
border-radius: 2px 2px 0 0;
background: #fff;
color: #311d0a;
line-height: 24px;
}
.tab:hover {
background: #eeeeee;
}
.active {
background: #f7c9c9;
}
</style>
요소 컴포넌트의 액티브 상태를 스스로 판단하게 하기
어떤 컴포넌트가 선택되어 있는 상태인지 판단해야 할 상황이 굉장히 많습니다.
현재 샘플에서는 부모로부터 전달받은 currentId
속성을 자신의 ID와 비교해서, 자신이 액티브 상태(선택되어 있는 상태)인지 확인하고 있습니다. 굉장히 자주 사용하는 형태입니다.