예약 포털 (Vue3 + Firebase) - 서비스 오픈까지

17. 동네 포털 - v-expansion-panels, v-data-table, vuedraggable

그랜파 개발자 2025. 6. 7. 17:49

테이크아웃 커피점 온라인 주문 개발 준비

테이크아웃 커피점의 메뉴 관리를 위하여 몇가지 UI 컴포넌트 (UI Components)들에 대해 알아 봅니다.

 

각 메뉴는 카테고리별로 분류하여 보여 주고,

표 형식으로 메뉴 데이터를 나타내고,

메뉴의 순서를 변경하기 위하여 드래그 앤 드롭(Drag & Drop) 기능을 사용합니다.

 

GitHub

https://github.com/inetsos/downtown

 

GitHub - inetsos/downtown: 동네 포털 - Vue 3 + Firebase

동네 포털 - Vue 3 + Firebase. Contribute to inetsos/downtown development by creating an account on GitHub.

github.com

 

v-expansion-panels, v-data-table, vuedraggable

v-expansion-panels

v-expansion-panels는 Vuetify에서 제공하는 UI 컴포넌트로,

여러 개의 내용을 아코디언(accordion) 방식으로 펼치고 접을 수 있게 해주는 구성 요소입니다.

주로 FAQ, 설정 페이지, 상세 정보 보기 등에서 사용됩니다.


✅ 기본 구조

<template>
  <v-expansion-panels>
    <v-expansion-panel>
      <v-expansion-panel-title>패널 1</v-expansion-panel-title>
      <v-expansion-panel-text>내용 1</v-expansion-panel-text>
    </v-expansion-panel>

    <v-expansion-panel>
      <v-expansion-panel-title>패널 2</v-expansion-panel-title>
      <v-expansion-panel-text>내용 2</v-expansion-panel-text>
    </v-expansion-panel>
  </v-expansion-panels>
</template>

✅ 주요 컴포넌트

컴포넌트 설명
v-expansion-panels 전체 아코디언 컨테이너
v-expansion-panel 각 패널을 감싸는 요소
v-expansion-panel-title 클릭 가능한 제목 부분
v-expansion-panel-text 펼쳐졌을 때 보여질 내용

✅ 주요 Props

📌 v-expansion-panels

Prop 설명
multiple 여러 패널을 동시에 열 수 있게 함
accordion 항상 하나의 패널만 열리게 함 (기본값)
model-value 현재 열려 있는 패널의 인덱스(들)
readonly 열고 닫기 비활성화
disabled 전체 패널 비활성화

📌 v-expansion-panel

Prop 설명
value 해당 패널의 고유 식별자 또는 인덱스
disabled 개별 패널 비활성화

✅ 열려 있는 패널 제어 (v-model 사용)

<template>
  <v-expansion-panels v-model="panel">
    <v-expansion-panel title="항목 1" text="내용 1" />
    <v-expansion-panel title="항목 2" text="내용 2" />
  </v-expansion-panels>
</template>

<script setup>
const panel = ref(0) // 0번째 패널이 기본으로 열림
</script>

multiple 옵션을 사용하면 배열로 제어할 수 있습니다.


✅ 스타일 및 확장

Vuetify의 Theme, Slot, Icon 등을 활용해 커스터마이징도 가능합니다.

v-data-table

v-data-table은 Vuetify에서 제공하는 강력한 표 형식의 데이터 표시 컴포넌트입니다. 데이터 목록을 표로 보여주고, 정렬, 페이징, 필터링, 선택, 사용자 정의 셀 렌더링 등 다양한 기능을 제공합니다.


✅ 기본 예제

<template>
  <v-data-table
    :headers="headers"
    :items="desserts"
    class="elevation-1"
  />
</template>

<script setup>
const headers = [
  { text: '디저트', value: 'name' },
  { text: '칼로리', value: 'calories' },
  { text: '지방(g)', value: 'fat' }
]

const desserts = [
  { name: '초콜릿 케이크', calories: 356, fat: 16 },
  { name: '아이스크림', calories: 237, fat: 9 },
  { name: '도넛', calories: 452, fat: 25 }
]
</script>

✅ 주요 Props

Prop 설명
items 테이블에 표시할 데이터 배열
headers 각 열(컬럼)의 정의 (text, value 등 포함)
items-per-page 한 페이지에 보여줄 아이템 수
sort-by 정렬할 필드
search 전체 텍스트 필터링 문자열
loading 로딩 상태 표시 여부
v-model 선택된 항목 제어 (다중 선택 시 배열)

✅ 헤더 정의 예시

const headers = [
  { text: '이름', value: 'name', sortable: true },
  { text: '나이', value: 'age', align: 'start' },
  { text: '액션', value: 'actions', sortable: false }
]

✅ 커스텀 셀 슬롯

<template>
  <v-data-table :headers="headers" :items="users">
    <template #item.actions="{ item }">
      <v-btn icon @click="edit(item)">
        <v-icon>mdi-pencil</v-icon>
      </v-btn>
    </template>
  </v-data-table>
</template>

✅ 기능 예시

  • 페이징: 기본 지원
  • 정렬: 헤더 클릭으로 정렬 가능
  • 검색 필터링: search prop 사용
  • 선택: show-select prop 추가
  • 로딩 스피너: loading prop

vuedraggable

vuedraggable는 Vue.js에서 드래그 앤 드롭(Drag & Drop) 기능을 쉽게 구현할 수 있게 해주는 인기 라이브러리입니다. 이 라이브러리는 SortableJS를 기반으로 만들어졌으며, 리스트 재정렬이나 카드 이동 같은 UI 기능을 쉽게 구현할 수 있게 도와줍니다.


✅ 주요 특징

  • 배열을 자동으로 업데이트
  • 리스트 간 이동 지원 (drag between lists)
  • v-model을 통해 리스트 바인딩
  • 다양한 이벤트 지원 (drag, start, end 등)
  • transition-group과 호환

✅ 설치 방법

npm install vuedraggable

✅ 기본 사용법

<template>
  <draggable v-model="items" item-key="id">
    <template #item="{ element }">
      <div class="item">{{ element.name }}</div>
    </template>
  </draggable>
</template>

<script setup>
import draggable from 'vuedraggable'

const items = ref([
  { id: 1, name: '🍎 Apple' },
  { id: 2, name: '🍌 Banana' },
  { id: 3, name: '🍇 Grape' }
])
</script>

<style>
.item {
  padding: 8px;
  margin: 4px 0;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
}
</style>

✅ 주요 Props

Prop 설명
v-model 드래그할 리스트 (배열)
item-key 각 항목의 고유 key 값
group 여러 리스트 간 이동할 때 그룹 이름
tag 감싸는 HTML 태그 (div, ul 등)
handle 특정 핸들러(예: .drag-handle)만 드래그 허용
disabled 드래그 비활성화 여부

✅ 주요 이벤트

이벤트 설명
@start 드래그 시작 시 호출
@end 드래그 끝났을 때 호출
@change 배열 순서가 바뀌었을 때
@add 다른 리스트에서 항목이 추가될 때
@remove 리스트에서 항목이 제거될 때