Vue 3 플러그인, 컴포저블, Provide/Inject, 커스텀 디렉티브

sean k·2025년 3월 22일
0

개념정리

목록 보기
3/4

🚀 Vue 3에서 자주 사용하는 핵심 기능들 — 플러그인, 컴포저블, provide/inject, 커스텀 디렉티브 — 각각의 역할과 차이점을 한 눈에 정리해봅니다.

기능한 줄 요약 설명언제 써야 할까?
📦 플러그인앱 전체에서 공통 기능을 설정할 때 사용$api, $log 등 전역 기능이 필요할 때
🧩 컴포저블컴포넌트 내부 로직을 재사용할 때 적합여러 컴포넌트에서 동일한 상태 관리나 로직이 반복될 때
🔗 provide / inject조상 컴포넌트에서 자식 컴포넌트로 데이터 전달설정값이나 공통 데이터를 자식 컴포넌트에 내려줄 때
🎯 커스텀 디렉티브엘리먼트에 직접 동작을 붙일 때 사용포커스 자동 부여, 외부 클릭 감지 등 DOM 조작이 필요할 때

🧩 Vue 3 주요 기능 비교표

항목📦 플러그인🧩 컴포저블🔗 provide / inject🎯 커스텀 디렉티브
주요 목적앱 전체 설정, 전역 기능 추가재사용 가능한 로직 분리조상 → 자식 간 데이터 전달DOM 직접 제어
사용 위치main.jsapp.use()컴포넌트 내부 setup()setup()provide, inject엘리먼트에 디렉티브로 사용 (v-*)
전역 설정 가능✅ (app.config, app.component 등)
전역 속성 추가✅ ($log, $api 등)
재사용 가능✅ (라이브러리처럼 배포 가능)✅ (로직 중심 재사용)✅ (여러 컴포넌트에서 공유 가능)✅ (디렉티브 재등록 가능)
DOM 직접 접근제한적 (ref 등으로 가능)✅ (focus, scroll 등)
예시Vue Router, i18n, ToastuseAuth(), useDarkMode()테마 설정, 글로벌 서비스 공유v-focus, v-scroll
Vue 내장 기능 의존많이 사용 (app.*)Composition API만 사용Composition API만 사용Directive API 사용

🔍 각 기능 예시 코드

📦 플러그인 예시

// myPlugin.js
export default {
  install(app, options) {
    app.config.globalProperties.$sayHello = () => console.log('Hello!');
    app.provide('pluginData', options?.message || 'Default Message');
  }
}

// main.js
import myPlugin from './myPlugin';
app.use(myPlugin, { message: 'Hello from plugin!' });

🧩 컴포저블 예시

// useCounter.js
import { ref } from 'vue';

export function useCounter() {
  const count = ref(0);
  const increment = () => count.value++;
  return { count, increment };
}

// 컴포넌트 내부
const { count, increment } = useCounter();

🔗 Provide / Inject 예시

<!-- ParentComponent.vue -->
<script setup>
import { provide } from 'vue';
provide('message', 'Hello from parent!');
</script>

<!-- ChildComponent.vue -->
<script setup>
import { inject } from 'vue';
const message = inject('message');
</script>

<template>
  <div>{{ message }}</div>
</template>

🎯 커스텀 디렉티브 예시

// directives/v-focus.js
export default {
  mounted(el) {
    el.focus();
  }
}

// main.js
import vFocus from './directives/v-focus';
app.directive('focus', vFocus);

// inputComponent.vue
<!-- 사용 -->
<input v-focus />

🔌 실무에서 자주 쓰는 플러그인 활용 예

Vue 플러그인은 전역 기능을 설정하거나 앱 전체에서 반복되는 로직을 쉽게 공유할 수 있어요.
아래는 실무에서 provide/inject 방식으로 많이 사용하는 전형적인 예시입니다:

사용 예설명
$apiHTTP 요청 관련 함수들을 묶어서 전역에서 사용 (getUser(), getPosts() 등)
$auth로그인 상태, 사용자 정보, 토큰 처리 등 인증 관련 로직 공유
$logger개발 중 콘솔 로그 또는 에러 로깅 기능 전역 제공
$toast알림/토스트 메시지 전역 호출 ($toast.success('완료!'))

📦 $api 플러그인

// plugins/api.js
export default {
  install(app, options) {
    const api = {
      getUser() {
        return fetch(`${options.baseUrl}/user`).then(res => res.json())
      },
      getPosts() {
        return fetch(`${options.baseUrl}/posts`).then(res => res.json())
      }
    }

    app.provide('$api', api)
  }
}

🔐 $auth 플러그인

// plugins/auth.js
export default {
  install(app) {
    const auth = {
      isLoggedIn: () => !!localStorage.getItem('token'),
      getToken: () => localStorage.getItem('token'),
      login(token) {
        localStorage.setItem('token', token)
      },
      logout() {
        localStorage.removeItem('token')
      }
    }

    app.provide('$auth', auth)
  }
}

🧾 $logger 플러그인

// plugins/logger.js
export default {
  install(app) {
    const logger = {
      log: (...args) => console.log('[LOG]', ...args),
      warn: (...args) => console.warn('[WARN]', ...args),
      error: (...args) => console.error('[ERROR]', ...args)
    }

    app.provide('$logger', logger)
  }
}

🛎️ $toast 플러그인 (예: 간단한 alert 기반)

// plugins/toast.js
export default {
  install(app) {
    const toast = {
      success: (msg) => alert(`✅ Success: ${msg}`),
      error: (msg) => alert(`❌ Error: ${msg}`)
    }

    app.provide('$toast', toast)
  }
}

🧩 main.js에서 등록하기

import { createApp } from 'vue'
import App from './App.vue'

import apiPlugin from './plugins/api'
import authPlugin from './plugins/auth'
import loggerPlugin from './plugins/logger'
import toastPlugin from './plugins/toast'

const app = createApp(App)

app.use(apiPlugin, { baseUrl: 'https://jsonplaceholder.typicode.com' })
app.use(authPlugin)
app.use(loggerPlugin)
app.use(toastPlugin)

app.mount('#app')

✅ 컴포넌트에서 사용 예시

<script setup>
import { inject } from 'vue'

const $api = inject('$api')
const $auth = inject('$auth')
const $logger = inject('$logger')
const $toast = inject('$toast')

// 예시 사용
onMounted(async () => {
  if ($auth.isLoggedIn()) {
    const user = await $api.getUser()
    $logger.log('User loaded:', user)
    $toast.success('사용자 정보를 불러왔습니다!')
  } else {
    $toast.error('로그인이 필요합니다.')
  }
})
</script>

💡 app.provide()를 활용한 플러그인은 Composition API와 궁합이 좋고,
inject()로 필요한 곳에서만 선택적으로 사용할 수 있어 유지보수가 편해요.

0개의 댓글