์ž‘์„ฑ: 2026-03-04 05:39:06์ˆ˜์ •: 2026-03-04 05:39:06

Nuxt ๋Œ€์‹œ๋ณด๋“œ ํ”„๋กœ์ ํŠธ ์‹œ๋ฆฌ์ฆˆ (5): ๋ฐ์ดํ„ฐ ์‹œ๊ฐํ™” ๋ฐ ํŽ˜์ด์ง€ ๊ตฌํ˜„

์‹œ๋ฆฌ์ฆˆ์˜ ๋งˆ์ง€๋ง‰ ๋‹จ๊ณ„์—์„œ๋Š” Naive UI์˜ DataTable๊ณผ ์š”์•ฝ ์นด๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋Œ€์‹œ๋ณด๋“œ ๋ฉ”์ธ ํŽ˜์ด์ง€๋ฅผ ์™„์„ฑํ•ฉ๋‹ˆ๋‹ค.


1. ๋Œ€์‹œ๋ณด๋“œ ํ™ˆ ํŽ˜์ด์ง€ (pages/index.vue)

์ƒ๋‹จ์—๋Š” ์ง€ํ‘œ ์š”์•ฝ ์นด๋“œ๋ฅผ, ํ•˜๋‹จ์—๋Š” ์ƒ์„ธ ๋ฐ์ดํ„ฐ ํ‘œ๋ฅผ ๋ฐฐ์น˜ํ•ฉ๋‹ˆ๋‹ค.

<template>
  <div class="flex flex-col gap-6">
    <!-- 1. ์ง€ํ‘œ ์š”์•ฝ (Grid) -->
    <div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
      <div v-for="item in summary" :key="item.title" class="card-base">
        <div class="text-gray-500 text-sm">{{ item.title }}</div>
        <div class="text-2xl font-bold mt-1">{{ item.value }}</div>
        <div :class="item.diff > 0 ? 'text-green-500' : 'text-red-500'" class="text-xs mt-2">
          {{ item.diff > 0 ? 'โ–ฒ' : 'โ–ผ' }} {{ Math.abs(item.diff) }}%
        </div>
      </div>
    </div>
 
    <!-- 2. ๋ฐ์ดํ„ฐ ํ‘œ -->
    <div class="card-base">
      <h3 class="text-lg font-bold mb-4">์ตœ๊ทผ ํ™œ๋™ ๋‚ด์—ญ</h3>
      <n-data-table
        :columns="columns"
        :data="data"
        :pagination="pagination"
        :bordered="false"
      />
    </div>
  </div>
</template>
 
<script setup>
const summary = [
  { title: '์ด ๋ฐฉ๋ฌธ์ž', value: '128,430', diff: 12.5 },
  { title: '๋งค์ถœ์•ก', value: 'โ‚ฉ4,250,000', diff: -3.2 },
  { title: '์‹ ๊ทœ ๊ฐ€์ž…', value: '1,204', diff: 24.8 },
  { title: '์ดํƒˆ๋ฅ ', value: '2.4%', diff: -1.5 },
]
 
const columns = [
  { title: 'ID', key: 'id' },
  { title: '์‚ฌ์šฉ์ž', key: 'name' },
  { title: 'ํ™œ๋™', key: 'action' },
  { title: '์‹œ๊ฐ„', key: 'date' },
]
 
const data = [
  { id: 1, name: 'ํ™๊ธธ๋™', action: '๋กœ๊ทธ์ธ', date: '2026-03-04 10:20' },
  { id: 2, name: '๊น€์ฒ ์ˆ˜', action: '๊ฒฐ์ œ ์™„๋ฃŒ', date: '2026-03-04 10:25' },
  // ... ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ
]
 
const pagination = { pageSize: 10 }
</script>

2. Naive UI DataTable์˜ ๊ฐ•์ 

  • ์„ฑ๋Šฅ: ์ˆ˜๋งŒ ๊ฐœ์˜ ํ–‰๋„ ๊ฐ€์ƒ ์Šคํฌ๋กค(Virtual Scroll)์„ ํ†ตํ•ด ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ํƒ€์ž… ์•ˆ์ •์„ฑ: ์ปฌ๋Ÿผ ์ •์˜ ์‹œ TypeScript๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ง€์›ํ•˜์—ฌ ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์‰ฝ์Šต๋‹ˆ๋‹ค.
  • ํ™•์žฅ์„ฑ: ๋ Œ๋”๋ง ํ•จ์ˆ˜(render)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์…€ ์•ˆ์— ๋ฒ„ํŠผ์ด๋‚˜ ํƒœ๊ทธ๋ฅผ ์‰ฝ๊ฒŒ ๋„ฃ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3. ๋Œ€์‹œ๋ณด๋“œ ๊ณ ๋„ํ™”๋ฅผ ์œ„ํ•œ ์ œ์•ˆ

  1. ์ฐจํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์—ฐ๋™: echarts๋‚˜ chart.js๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์‹œ๊ฐํ™”ํ•ด ๋ณด์„ธ์š”.
  2. ๋‹คํฌ ๋ชจ๋“œ: Naive UI์˜ darkTheme์™€ UnoCSS์˜ dark: ์ ‘๋‘์‚ฌ๋ฅผ ์—ฐ๋™ํ•˜๋ฉด ์‰ฝ๊ฒŒ ๊ตฌํ˜„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ถŒํ•œ ์ œ์–ด: Pinia์˜ authStore ์ •๋ณด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋ฉ”๋‰ด ๋…ธ์ถœ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๋ฏธ๋“ค์›จ์–ด๋ฅผ ์ž‘์„ฑํ•ด ๋ณด์„ธ์š”.

4. ์‹œ๋ฆฌ์ฆˆ๋ฅผ ๋งˆ์น˜๋ฉฐ

์ง€๊ธˆ๊นŒ์ง€ Nuxt, Pinia, Naive UI, UnoCSS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„๋Œ€์ ์ธ ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ์ „ ๊ณผ์ •์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ์กฐํ•ฉ์€ ๊ฐ€๋…์„ฑ ๋†’์€ ์ฝ”๋“œ์™€ ์••๋„์ ์ธ ์„ฑ๋Šฅ์„ ๋™์‹œ์— ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

์ด์ œ ์—ฌ๋Ÿฌ๋ถ„๋งŒ์˜ ๋ฉ‹์ง„ ๊ด€๋ฆฌ์ž ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์„ธ์š”! ๐Ÿš€