#基礎から学ぶVue.jsの切り替えタブを、作り替えたい
###参考にするお手本
■基礎から学ぶVue.js 切り替えタブ実装例
https://cr-vue.mio3io.com/examples/tab.html#%E3%83%87%E3%83%A2
上記の実装例では、
・index.vueという親コンポーネント、
・TabItem.vueという子コンポーネント
の2つ.vueファイルに分けて切り替えタブを実装しています。
###しかし今回の目的は
1つのファイルにまとめて切り替えタブを作っていきます。
つまるところ、index.vueだけで済むように作り替えていきます。
#作り替えてみた、完成版
<template>
<div class="example">
<div class="tabs">
<template v-bind:value="currentId">
<button
v-for=" item in list"
:key="item.id"
@click="idClickHandler(item)"
:class="[active(item.id), 'tab']"
>{{ item.label }}</button>
</template>
</div>
<div class="contents">
<transition>
<section class="item" :key="currentId">{{ current.content }}</section>
</transition>
</div>
</div>
</template>
<script>
export default {
data() {
return {
currentId: 1,
list: [
{ id: 1, label: "Tab1", content: "コンテンツ1" },
{ id: 2, label: "Tab2", content: "コンテンツ2" },
{ id: 3, label: "Tab3", content: "コンテンツ3" }
]
};
},
computed: {
active() {
return function(id) {
return this.currentId === id ? "active" : false;
};
},
current() {
return this.list.find(el => el.id === this.currentId) || {};
}
},
methods: {
idClickHandler(item) {
return (this.currentId = item.id);
}
}
};
</script>
<style scoped>
.tab {
border-radius: 2px 2px 0 0;
background: #fff;
color: #311d0a;
line-height: 24px;
}
.tab:hover {
background: #eeeeee;
}
.active {
background: #f7c9c9;
}
.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>
#変更したところ
- (親)v-modelと(子)$emitを使ってイベントと値を渡していた → v-modelを廃止して、@click後の処理をmethodsに書いた
- (子)で使えていた算出プロパティ(computed)内の、this.idを使ったactiveクラス → computedでは引数が使えないため、function関数をそのまま返す処理に変更して引数を使えるようにした
#気をつけるところ
computed内、methods内で使用する値は、当たり前ですが変更する箇所が多いです。
TabItem.vueで使用する際になぜ this.値 と使えてたかというと、propsで値をもらっていたことでdataオプションのように使用できた為です。
そのため、index.vue内で this.値 を使用したくても出来ません。
v-forで回したlist内のオブジェクトitemを選択しているよ〜と伝える必要があります。
それを常に引数で渡す!!ことを心がけると上手くいきます。
ちなみに、template(html)で指定する引数とscript内で指定する引数は名前が違っても構いません。が、分かりやすくはしてください。
#JSの機能か?Vueの機能か?
私は常にこの2つで迷って、正解を見つけ出すのに時間かかったりしてました。
Vue歴もJS歴も浅い時には、つねに2つのドキュメントを行き来するのではないかなと思います。
その中で迷ったことはこちらです。
・current()computedで使用するelは、何なんだろう。
■MDN find()メソッド
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find
なるほど、JSの機能なのですね。
#以上
ありがとうございました。