본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

Tabs 탭

원문 보기 위키 갱신

탭을 전환하는 컴포넌트예요.

출처: 문서

본문

언제 사용하나요

사용자가 같은 수준의 영역으로 큰 덩어리의 콘텐츠를 수납하고 보여줘야 해서 화면을 깔끔하게 유지하고 싶을 때 사용해요.

기본 사용법

:::demo

<template>
  <d-tabs v-model="id">
    <d-tab id="tab1" title="Tab1">
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab1');
    return {
      id,
    };
  },
});
</script>

:::

Pills 타입

:::demo

<template>
  <d-tabs type="pills" v-model="id">
    <d-tab id="tab1" title="Tab1">
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab1');
    return {
      id,
    };
  },
});
</script>

:::

Options 타입

:::demo

<template>
  <d-tabs type="options" v-model="id" custom-width="100px">
    <d-tab id="tab1" title="Tab1">
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab1');
    return {
      id,
    };
  },
});
</script>

:::

Wrapped 타입

:::demo

<template>
  <d-tabs type="wrapped" v-model="id">
    <d-tab id="tab1" title="Tab1">
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab1');
    return {
      id,
    };
  },
});
</script>

:::

Slider 타입

:::demo

<template>
  <d-tabs type="slider" v-model="id">
    <d-tab id="tab1" title="Tab1">
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab1');
    return {
      id,
    };
  },
});
</script>

:::

탭 비활성화

:::demo

<template>
  <d-tabs v-model="id">
    <d-tab id="tab1" title="Tab1" disabled>
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab2');
    return {
      id,
    };
  },
});
</script>

:::

tab 전환 가로채기

:::demo

<template>
  <d-tabs v-model="id" :before-change="beforeChange" @active-tab-change="activeTabChange">
    <d-tab id="tab1" title="Tab1">
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab3');
    const beforeChange = (tab) => {
      if (tab === 'tab1') {
        id.value = 'tab2';
        return false;
      } else {
        return true;
      }
    };
    const activeTabChange = (id) => {
      console.log(id, 'activeTabChange');
    };
    return {
      id,
      beforeChange,
      activeTabChange,
    };
  },
});
</script>

:::

추가/삭제

탭을 추가하고 삭제해요.

tabs

d-tabs에 closeable, addable을 설정하면 탭을 닫고 새로 추가하는 버튼이 나타나요. tab-add와 tab-remove 이벤트는 각각 추가 버튼과 삭제 버튼이 클릭될 때 발생해요.

:::demo

<template>
  <d-tabs v-model="editableId" closeable addable @tab-add="tabAdd" @tab-remove="tabRemove" @tab-change="onTabChange">
    <d-tab v-for="tab in tabs" :key="tab.id" :id="tab.id" :title="tab.title">
      <p>{{ tab.title }} Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const editableId = ref('tab1');
    const tabs = ref([
      { id: 'tab1', title: 'Tab1' },
      { id: 'tab2', title: 'Tab2' },
      { id: 'tab3', title: 'Tab3' },
    ]);
    const tabAdd = () => {
      for (let i = 1; i <= tabs.value.length + 1; i++) {
        if (!tabs.value.find((item) => item.id === `tab${i}`)) {
          tabs.value.push({ id: `tab${i}`, title: `Tab${i}` });
          editableId.value = `tab${i}`
          break;
        }
      }
    };
    const tabRemove = (targetTab) => {
      if (tabs.value.length === 1) {
        return;
      }
      const tempTabs = tabs.value;
      let activeName = editableId.value;

      if (activeName === targetTab.id) {
        tempTabs.forEach((tab, index) => {
          if (tab.id === targetTab.id) {
            const nextTab = tempTabs[index + 1] || tempTabs[index - 1];
            if (nextTab) {
              activeName = nextTab.id;
            }
          }
        });
      }

      editableId.value = activeName;
      tabs.value = tempTabs.filter((tab) => tab.id !== targetTab.id);
    };

    const onTabChange = (id, type) => {
      console.log(id);
      console.log(type);
    };
    return {
      editableId,
      tabs,
      tabAdd,
      tabRemove,
      onTabChange,
    };
  },
});
</script>

:::

tab

d-tab의 닫기 버튼은 개별적으로 제어할 수 있어요. d-tabs의 closeable 속성이 true이면 d-tab의 closeable 속성은 적용되지 않아요.

:::demo

<template>
  <d-tabs v-model="soloEditableId">
    <d-tab v-for="tab in soloTabs" :key="tab.id" :id="tab.id" :title="tab.title" :closeable="tab.closeable">
      <p>{{ tab.title }} Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const soloEditableId = ref('tab1');
    const soloTabs = ref([
      { id: 'tab1', title: 'Tab1', closeable: true },
      { id: 'tab2', title: 'Tab2', closeable: true },
      { id: 'tab3', title: 'Tab3', closeable: false },
    ]);

    return {
      soloEditableId,
      soloTabs,
    };
  },
});
</script>

:::

커스텀 템플릿

:::demo

<template>
  <d-tabs v-model="id">
    <d-tab id="tab1" title="Tab1">
      <template v-slot:title><d-icon name="code" class="mr-xxs" />代码</template>
      <p>Tab1 Content</p>
    </d-tab>
    <d-tab id="tab2" title="Tab2">
      <template v-slot:title><d-icon name="merge-request" class="mr-xxs" />合并请求</template>
      <p>Tab2 Content</p>
    </d-tab>
    <d-tab id="tab3" title="Tab3">
      <template v-slot:title><d-icon name="help" class="mr-xxs" />Issues</template>
      <p>Tab3 Content</p>
    </d-tab>
  </d-tabs>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const id = ref('tab3');
    return {
      id,
    };
  },
});
</script>

:::

탭 위치 설정

tab-position으로 탭 라벨의 위치를 설정할 수 있고, 네 방향 'top' | 'right' | 'bottom' | 'left'을 지원해요.

:::demo

<template>
  <div>
    <d-radio-group direction="row" v-model="tabPosition">
      <d-radio-button v-for="item in groupFilterList1" :key="item" :value="item">
        {{ item }}
      </d-radio-button>
    </d-radio-group>
    <d-tabs :tab-position="tabPosition" v-model="tabPositionId">
      <d-tab id="tab1" title="Tab1">
        <p>Tab1 Content</p>
      </d-tab>
      <d-tab id="tab2" title="Tab2">
        <p>Tab2 Content</p>
      </d-tab>
      <d-tab id="tab3" title="Tab3">
        <p>Tab3 Content</p>
      </d-tab>
    </d-tabs>
  </div>
</template>
<script>
import { defineComponent, ref } from 'vue';

export default defineComponent({
  setup() {
    const tabPositionId = ref('tab1');
    const tabPosition = ref('top');
    const groupFilterList1 = ref(['top', 'right', 'bottom', 'left']);
    return {
      tabPositionId,
      tabPosition,
      groupFilterList1,
    };
  },
});
</script>

:::

Tabs 파라미터

파라미터 타입 기본값 설명
type ITabsType 'tabs' 선택, 탭 그룹 타입
show-content boolean true 선택, 탭 대응 콘텐츠 표시 여부
v-model string -- 선택, 현재 활성 탭. 값은 탭의 id
custom-width string -- 선택, 탭 너비 커스텀
vertical boolean false 선택, 세로 표시 여부
before-change function|Promise -- tab 전환 전 콜allback 함수. boolean을 반환하며, false를 반환하면 tab 전환을 막을 수 있음
reactivable boolean false 선택, 현재 활성 tab 클릭 시 active-tab-change 이벤트 트리거 여부.
true는 트리거 허용, false는 트리거 불허
closeable boolean false 선택, tab 삭제 아이콘 표시 여부
addable boolean false 선택, tab 추가 아이콘 표시 여부
tab-position ITabPositionType 'top' 선택, 탭 위치

Tabs 이벤트

파라미터 타입 설명
active-tab-change function(string|number) 선택, 탭 전환 콜백 함수. 현재 활성 탭의 id 반환
tab-remove function(tab, event) 선택, tab 제거 버튼 클릭 시 트리거. tab은 삭제된 tab 객체
tab-add function() 선택, tab 추가 버튼 클릭 시 트리거
tab-change function(string|number) 선택, tab 추가/삭제 콜백 함수. 조작한 탭 id와 operation(add | delete) 반환

Tab 파라미터

파라미터 타입 기본값 설명
id number|string -- 선택, 탭 id 값. 유일한 값으로 설정 필요
title string -- 선택, 탭 제목
disabled boolean false 선택, 탭 사용 불가 여부
closeable boolean false 선택, 탭 닫기 가능 여부. tabs의 closeable이 true면 이 속성은 무효

Tab 슬롯

이름 설명
title 탭 제목 커스텀

타입 정의

ITabsType

type ITabsType = 'tabs' | 'pills' | 'options' | 'wrapped' | 'slider';

ITabPositionType

type ITabPositionType = 'top' | 'right' | 'bottom' | 'left';

더 알아보기 (Learn more)

type으로 tabs·pills·options·wrapped·slider 다섯 가지 스타일을 고를 수 있고, before-change로 전환을 가로채거나 closeable/addable로 탭 추가·삭제 UI를 붙일 수 있어요.