🦒
Vue3 タブUI
作成日:
2024/04/12
0
今回はcomposition APIでタブ機能を作った。
親でコンテンツをいくつ入れるかできるので子コンポーネントは使い回しが出来て便利だと思う。
子コンポーネント
まずはタブの数分、繰り返し表示したいのでv-for
を使い、クリックされたタブのidと内容(text)を取得するためにv-on:click
を設定しタブナンバーの中身を引数に渡す。
クリックされたクラスをisActive
を付与したいので===タブ.id
*liタグの中身.numberは別になんでもいい
タブで押された内容を下のタブに表示するため、isActiveで判断しデフォルト(最初に表示する文)とそれ以外を入れるためにv-else
を設定する。
<template>
<!-- タブ -->
<ul>
<li v-for="△△△ in ○○○" :key="△△△.id" @click="関数名(△△△.id,△△△.text)" :class="{ 'isActive': isActive === △△△.id }">{{△△△.number}}</li>
</ul>
<!-- 押されたタブの中身 -->
<ul>
<li v-if="isActive === '1'">{{ defoText }}</li>
<li v-else>{{ isText }}</li>
</ul>
</template>
次に、jsの設定。
○○○の部分は親コンポーネントから設定するのでprops
クリック関数でpropsで渡ってきた○○○を△△△に分け、idとtextを引数に渡し、クリックされたタブのid(numberでもいい)をisActiveに代入し、isTextの中身も代入する
クリックされる前(最初の表示)でisActiveの初期値などを設定する
<script setup lang="ts">
import { ref,defineProps } from "vue";
const isActive = ref("1") //初期値を1に設定
const isText = ref("") //初期値を空文字にする
defineProps({
○○○: Array, //配列の中にobjだが、渡ってくるのは一番外の配列になるため
defoText: String,
})
const 関数名 = function(num:string,txt:string):void{
//引数にliがクリックされた時に渡ってくる物を入れる
isActive.value = num;
isText.value = txt;
}
</script>
親コンポーネント
importで読み込み、タグを入れる(省略)
タブの中身や個数をオブジェクトに設定する
<template>
<コンポーネント名 :○○○="tab" :defoText="defoText">
</template>
<script setup lang="ts">
// interfaceを決める
interface tabinter{
number: Number,
id: String,
text: String,
}
// タブを作る
const tab:tabinter[] = [
{number: 1, id: "1", text: "このコンテンツは1です"},
{number: 2, id: "2", text: "このコンテンツは2です"},
]
// デフォルト文字を取得するためfind関数を使う
const itemTxt = tab.find((tabitem):boolean => tabitem.id === '1')//findはture or falceを返すのでboolean
const tabfirst = itemTxt?.text;
const defoText = ref(tabfirst)
</script>
完成系
//子コンポーネント
<template>
<ul class="tabs">
<li v-for="something in somethingList" :key="something.id" @click="change(something.id,something.text)" :class="{ 'isActive': isActive === something.id}">
タブ{{ something.number }}
</li>
</ul>
<!-- 親から子へ -->
<ul class="contents">
<li v-if="isActive === '1'">{{ defoText }}</li>
<li v-else>{{ isText }}</li>
</ul>
</template>
<script setup lang="ts">
import { ref, defineProps } from 'vue';
const isActive = ref("1");
const isText = ref("");
const change = function(num:string,txt:string):void {
isActive.value = num;
isText.value = txt;
}
defineProps({
somethingList: Array,
defoText: String
})
</script>
// 親コンポーネント
<template>
<NewList :somethingList="tab" :defoText="defoText"></NewList>
</template>
<script setup lang="ts">
import { ref } from 'vue';
// tab interface
interface tabinter {
number: Number,
id: String,
text: String,
}
// tab
const tab:tabinter[] = [
{number: 1, id: "1", text: "このコンテンツは1です"},
{number: 2, id: "2", text: "このコンテンツは2です"},
{number: 3, id: "3", text: "このコンテンツは3です"},
{number: 4, id: "4", text: "このコンテンツは4です"},
{number: 5, id: "5", text: "このコンテンツは5です"},
{number: 6, id: "6", text: "このコンテンツは99です"},
]
const itemTxt = tab.find((tabitem):boolean => tabitem.id === '1')
const tabfirst = itemTxt?.text;
const defoText = ref(tabfirst)
<script>
フロントエンドエンジニアを頑張って勉強中。
最近はVueやNuxtを勉強中です。
コミュニティなどあれば参加してみたいと思ってます。
どうぞ、生暖かい目で見ていただけると幸いです。