# 切り替えタブ
# デモ
あまり面白味がなかったので、トランジションでスライドっぽくしてみました。
# 使用している主な機能
クラスのデータバインディング 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 が現在選択されている要素の ID と一致するかを確認しています。