한국어

Vue.js 3 컴포지션 API를 심층적으로 탐색해 보세요. 전 세계 개발자를 위한 실용적인 예제와 모범 사례를 통해 재사용 가능하고 유지보수하기 쉬우며 테스트 용이한 Vue.js 애플리케이션 구축 방법을 배워보세요.

Vue.js 3 컴포지션 API: 글로벌 개발자를 위한 심층 분석

Vue.js는 접근하기 쉬운 학습 곡선과 강력한 기능 덕분에 최신 웹 애플리케이션을 구축하는 데 있어 빠르게 인기 있는 선택지가 되었습니다. Vue.js 3는 컴포넌트 로직을 구성하는 새로운 방식인 컴포지션 API를 도입하여 한 단계 더 나아갔습니다. 이 심층 분석은 컴포지션 API를 효과적으로 이해하고 활용하기 위한 포괄적인 가이드를 제공하며, 이를 통해 더 유지보수하기 쉽고 재사용 가능하며 테스트 용이한 Vue 애플리케이션을 구축할 수 있는 기술을 갖추게 될 것입니다.

컴포지션 API란 무엇인가?

컴포지션 API는 옵션을 선언하는 대신 가져온 함수를 사용하여 Vue 컴포넌트를 작성할 수 있게 해주는 API 집합입니다. 기본적으로 템플릿의 어느 위치에 나타나는지와 관계없이 관련된 로직을 함께 그룹화할 수 있습니다. 이는 코드를 사전에 정의된 카테고리에 따라 구성하도록 강제하는 옵션 API(data, methods, computed, watch)와 대조됩니다. 옵션 API는 코드를 *무엇*인지(데이터, 메서드 등)에 따라 구성하는 것으로 생각할 수 있는 반면, 컴포지션 API는 코드를 *무슨 일을 하는지*에 따라 구성할 수 있게 해줍니다.

컴포지션 API의 핵심은 setup() 함수를 중심으로 전개됩니다. 이 함수는 컴포넌트 내에서 컴포지션 API를 활용하기 위한 진입점입니다. setup() 내부에서는 컴포저블 함수를 사용하여 반응형 상태, 계산된 속성, 메서드 및 생명주기 훅을 정의할 수 있습니다.

왜 컴포지션 API를 사용해야 하는가?

컴포지션 API는 전통적인 옵션 API에 비해 특히 더 크고 복잡한 애플리케이션에서 여러 가지 이점을 제공합니다:

핵심 개념 이해하기

컴포지션 API를 뒷받침하는 핵심 개념들을 자세히 살펴보겠습니다:

1. setup()

앞서 언급했듯이, setup()은 컴포지션 API를 사용하기 위한 진입점입니다. 컴포넌트가 생성되기 전에 실행되는 컴포넌트 옵션입니다. setup() 내부에서 반응형 상태, 계산된 속성, 메서드 및 생명주기 훅을 정의한 다음, 템플릿에 노출하려는 값을 포함하는 객체를 반환합니다.

예제:

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}

이 예제에서는 ref를 사용하여 count라는 반응형 변수를 생성합니다. 또한 count의 값을 증가시키는 increment라는 메서드를 정의합니다. 마지막으로, countincrement를 포함하는 객체를 반환하여 컴포넌트의 템플릿에서 사용할 수 있도록 합니다.

2. refreactive를 이용한 반응형 상태

컴포지션 API는 반응형 상태를 만들기 위한 두 가지 핵심 함수인 refreactive를 제공합니다.

ref 사용 예제:

import { ref } from 'vue'

export default {
  setup() {
    const message = ref('Hello, Vue!')

    const updateMessage = (newMessage) => {
      message.value = newMessage
    }

    return {
      message,
      updateMessage
    }
  }
}

reactive 사용 예제:

import { reactive } from 'vue'

export default {
  setup() {
    const state = reactive({
      name: 'John Doe',
      age: 30
    })

    const updateName = (newName) => {
      state.name = newName
    }

    return {
      state,
      updateName
    }
  }
}

3. computed를 이용한 계산된 속성

계산된 속성은 다른 반응형 상태에서 파생되는 값입니다. 의존성이 변경될 때마다 자동으로 업데이트됩니다. computed 함수는 getter 함수를 인수로 받아 읽기 전용 반응형 ref를 반환합니다.

예제:

import { ref, computed } from 'vue'

export default {
  setup() {
    const firstName = ref('John')
    const lastName = ref('Doe')

    const fullName = computed(() => {
      return `${firstName.value} ${lastName.value}`
    })

    return {
      firstName,
      lastName,
      fullName
    }
  }
}

이 예제에서 fullNamefirstNamelastName에 의존하는 계산된 속성입니다. firstName이나 lastName이 변경될 때마다 fullName은 자동으로 업데이트됩니다.

4. watchwatchEffect를 이용한 감시자

감시자를 사용하면 반응형 상태의 변화에 반응할 수 있습니다. 컴포지션 API는 watchwatchEffect라는 두 가지 주요 방법으로 감시자를 생성합니다.

watch 사용 예제:

import { ref, watch } from 'vue'

export default {
  setup() {
    const count = ref(0)

    watch(
      count,
      (newValue, oldValue) => {
        console.log(`Count changed from ${oldValue} to ${newValue}`)
      }
    )

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}

watchEffect 사용 예제:

import { ref, watchEffect } from 'vue'

export default {
  setup() {
    const message = ref('Hello')

    watchEffect(() => {
      console.log(`Message is: ${message.value}`)
    })

    const updateMessage = (newMessage) => {
      message.value = newMessage
    }

    return {
      message,
      updateMessage
    }
  }
}

5. 생명주기 훅

컴포지션 API는 onMounted, onUpdated, onUnmounted와 같이 on으로 시작하는 함수를 통해 컴포넌트 생명주기 훅에 접근할 수 있습니다. 이 함수들은 콜백을 인수로 받으며, 해당 생명주기 훅이 트리거될 때 실행됩니다.

예제:

import { onMounted, onUnmounted } from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('Component is mounted')
    })

    onUnmounted(() => {
      console.log('Component is unmounted')
    })

    return {}
  }
}

컴포저블 함수 만들기

컴포지션 API의 진정한 힘은 재사용 가능한 컴포저블 함수를 만드는 능력에서 나옵니다. 컴포저블 함수는 단순히 컴포넌트 로직의 일부를 캡슐화하고 여러 컴포넌트에서 사용할 수 있는 반응형 상태와 함수를 반환하는 함수입니다.

예제: 마우스 위치를 추적하는 컴포저블 함수를 만들어 봅시다:

import { ref, onMounted, onUnmounted } from 'vue'

export function useMousePosition() {
  const x = ref(0)
  const y = ref(0)

  const updatePosition = (event) => {
    x.value = event.clientX
    y.value = event.clientY
  }

  onMounted(() => {
    window.addEventListener('mousemove', updatePosition)
  })

  onUnmounted(() => {
    window.removeEventListener('mousemove', updatePosition)
  })

  return {
    x,
    y
  }
}

이제 이 컴포저블 함수를 어떤 컴포넌트에서든 사용할 수 있습니다:

import { useMousePosition } from './useMousePosition'

export default {
  setup() {
    const { x, y } = useMousePosition()

    return {
      x,
      y
    }
  }
}

실용적인 예제 및 사용 사례

실제 시나리오에서 컴포지션 API를 어떻게 사용할 수 있는지 몇 가지 실용적인 예제를 살펴보겠습니다:

1. 데이터 가져오기

API에서 데이터를 가져오는 컴포저블 함수를 만드는 것은 일반적인 사용 사례입니다. 이를 통해 동일한 데이터 가져오기 로직을 여러 컴포넌트에서 재사용할 수 있습니다.

import { ref, onMounted } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)
  const loading = ref(true)

  onMounted(async () => {
    try {
      const response = await fetch(url)
      data.value = await response.json()
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  })

  return {
    data,
    error,
    loading
  }
}

그런 다음 이 컴포저블 함수를 다음과 같이 컴포넌트에서 사용할 수 있습니다:

import { useFetch } from './useFetch'

export default {
  setup() {
    const { data, error, loading } = useFetch('https://api.example.com/data')

    return {
      data,
      error,
      loading
    }
  }
}

2. 폼 유효성 검사

폼 유효성 검사는 컴포지션 API가 매우 유용할 수 있는 또 다른 영역입니다. 유효성 검사 로직을 캡슐화하는 컴포저블 함수를 만들어 여러 다른 폼에서 재사용할 수 있습니다.

import { ref } from 'vue'

export function useValidation() {
  const errors = ref({})

  const validateField = (fieldName, value, rules) => {
    let error = null
    for (const rule of rules) {
      if (rule === 'required' && !value) {
        error = 'This field is required'
        break
      } else if (rule === 'email' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
        error = 'Invalid email format'
        break
      }
    }

    if (error) {
      errors.value[fieldName] = error
    } else {
      delete errors.value[fieldName]
    }
  }

  return {
    errors,
    validateField
  }
}

컴포넌트에서의 사용법:

import { useValidation } from './useValidation'
import { ref } from 'vue'

export default {
  setup() {
    const { errors, validateField } = useValidation()
    const email = ref('')

    const validateEmail = () => {
      validateField('email', email.value, ['required', 'email'])
    }

    return {
      email,
      errors,
      validateEmail
    }
  }
}

3. 사용자 인증 관리

인증 로직은 종종 복잡하고 여러 컴포넌트에서 중복될 수 있습니다. 컴포지션 API를 사용하면 모든 인증 로직을 캡슐화하고 컴포넌트가 사용할 수 있는 깔끔한 API를 제공하는 컴포저블 함수를 만들 수 있습니다.

예제: (간략화)

import { ref } from 'vue'

export function useAuth() {
  const isLoggedIn = ref(false)
  const user = ref(null)

  const login = async (username, password) => {
    // API 호출 시뮬레이션
    await new Promise(resolve => setTimeout(resolve, 1000))
    isLoggedIn.value = true
    user.value = { username }
  }

  const logout = async () => {
    // API 호출 시뮬레이션
    await new Promise(resolve => setTimeout(resolve, 1000))
    isLoggedIn.value = false
    user.value = null
  }

  return {
    isLoggedIn,
    user,
    login,
    logout
  }
}

컴포지션 API 사용을 위한 모범 사례

컴포지션 API를 최대한 활용하려면 다음 모범 사례를 고려하십시오:

일반적인 함정과 이를 피하는 방법

컴포지션 API는 많은 이점을 제공하지만, 알아두어야 할 몇 가지 일반적인 함정도 있습니다:

컴포지션 API와 글로벌 팀

컴포지션 API는 다음을 촉진하여 글로벌 개발팀 내의 협업을 장려합니다:

결론

Vue.js 3 컴포지션 API는 Vue 애플리케이션의 구성, 재사용성 및 테스트 용이성을 크게 향상시킬 수 있는 강력한 도구입니다. 이 심층 분석에서 설명한 핵심 개념을 이해하고 모범 사례를 따르면, 컴포지션 API를 활용하여 전 세계 사용자를 위한 더 유지보수하기 쉽고 확장 가능한 애플리케이션을 구축할 수 있습니다. 컴포지션 API를 받아들이고 Vue.js 3의 잠재력을 최대한 발휘해 보세요.

자신의 프로젝트에서 컴포지션 API를 실험해보고 그것이 제공하는 무한한 가능성을 탐색해 보시기를 권장합니다. 즐거운 코딩 되세요!