프로그래밍 작업에서 코드의 재사용 가능성은 매우 중요한 요소입니다. 코드 재사용을 통해 코드베이스를 효율적으로 관리하고, 불필요한 코드 중복을 피할 수 있으며, 전반적인 개발 생산성을 향상시킬 수 있습니다. 특히 대규모 애플리케이션에서는 코드 재사용이 더욱 중요해지며, 이를 통해 복잡성을 줄이고 디버깅을 간소화할 수 있습니다.
Vue.js는 컴포저블이라는 강력한 기능을 통해 코드 재사용을 효율적으로 관리할 수 있도록 지원합니다. 컴포저블은 특정 로직을 캡슐화하는 함수로, 애플리케이션 전반에서 재사용하여 유사한 기능을 수행할 수 있습니다. 이를 통해 코드의 일관성을 유지하고 개발 시간을 단축할 수 있습니다.
과거에는 항상 컴포저블이었을까요?
Vue 3에서 컴포저블이 도입되기 이전에는 믹스인이라는 개념이 존재했습니다. 믹스인은 컴포넌트 로직을 캡처하여 여러 컴포넌트에서 재사용할 수 있도록 하는 기능입니다. 믹스인은 데이터, 메서드, 라이프사이클 훅 등 Vue.js 옵션을 포함하여 여러 컴포넌트에서 코드를 공유할 수 있도록 했습니다.
믹스인을 사용하려면, 우선 믹스인 로직을 별도의 파일로 구성해야 합니다. 그리고 나서, 해당 믹스인을 사용하려는 컴포넌트의 옵션 객체 내 `mixins` 속성에 추가하여 적용할 수 있었습니다. 예를 들어, 다음 코드는 양식 유효성 검사를 위한 믹스인의 예시를 보여줍니다.
export const formValidationMixin = { data() { return { formData: { username: '', password: '', }, formErrors: { username: '', password: '', }, }; }, methods: { validateForm() { this.formErrors = {}; if (!this.formData.username.trim()) { this.formErrors.username="Username is required."; } if (!this.formData.password.trim()) { this.formErrors.password = 'Password is required.'; } return Object.keys(this.formErrors).length === 0; }, }, };
이 코드 조각에서, `formValidationMixin`은 양식 데이터를 저장하는 `formData` 객체와 유효성 검사 오류를 저장하는 `formErrors` 객체를 포함하고 있습니다. 초기값은 모두 비어 있는 문자열로 설정되어 있습니다.
`validateForm` 메서드는 `formData`의 사용자 이름과 비밀번호 필드의 유효성을 검사합니다. 만약 필드가 비어있으면, 해당하는 오류 메시지를 `formErrors` 객체에 추가합니다. 만약 모든 필드가 유효하면, `formErrors` 객체가 비어있을 때 true를 반환합니다.
이 믹스인은 Vue 컴포넌트로 가져와서 Options 객체의 `mixin` 속성에 추가하여 사용할 수 있습니다. 아래 코드는 믹스인을 사용하는 컴포넌트의 예시입니다.
<template> <div> <form @submit.prevent="submitForm"> <div> <label for="username">Username:</label> <input type="text" id="username" v-model="formData.username" /> <span class="error">{{ formErrors.username }}</span> </div> <div> <label for="password">Password:</label> <input type="password" id="password" v-model="formData.password" /> <span class="error">{{ formErrors.password }}</span> </div> <button type="submit">Submit</button> </form> </div> </template> <script> import { formValidation } from "./formValidation.js"; export default { mixins: [formValidation], methods: { submitForm() { if (this.validateForm()) { alert("Form submitted successfully!"); } else { alert("Please correct the errors in the form."); } }, }, }; </script> <style> .error { color: red; } </style>
이 코드는 Options API 방식으로 작성된 Vue 컴포넌트를 보여줍니다. `mixins` 속성은 가져온 모든 믹스인을 포함하며, 이 경우 컴포넌트는 `formValidation` 믹스인의 `validateForm` 메서드를 사용하여 폼 제출 성공 여부를 사용자에게 알립니다.
컴포저블은 어떻게 사용할까요?
컴포저블은 특정 문제나 요구 사항에 맞춰 기능을 구현한 독립적인 JavaScript 파일입니다. 컴포저블은 `ref`나 `computed`와 같은 기능을 활용하여 Vue의 Composition API를 사용할 수 있습니다. Composition API에 대한 접근을 통해 여러 컴포넌트에서 재사용 가능한 기능을 만들 수 있습니다. 이러한 함수들은 Composition API의 `setup` 함수를 통해 Vue 컴포넌트로 쉽게 가져오고 통합할 수 있는 객체를 반환합니다.
컴포저블을 사용하려면, 프로젝트의 `src` 디렉토리에 새 JavaScript 파일을 만들어야 합니다. 대규모 프로젝트에서는 `src` 내에 폴더를 구성하고 다양한 컴포저블에 대한 별도의 JavaScript 파일을 생성하는 것이 좋습니다. 각 컴포저블의 이름은 해당 목적을 반영해야 합니다.
JavaScript 파일 내에서 필요한 기능을 정의합니다. 다음은 위에서 본 `formValidation` 믹스인을 컴포저블로 재구성한 예시입니다.
import { reactive } from 'vue'; export function useFormValidation() { const state = reactive({ formData: { username: '', password: '', }, formErrors: { username: '', password: '', }, }); function validateForm() { state.formErrors = {}; if (!state.formData.username.trim()) { state.formErrors.username="Username is required."; } if (!state.formData.password.trim()) { state.formErrors.password = 'Password is required.'; } return Object.keys(state.formErrors).length === 0; } return { state, validateForm, }; }
이 코드 스니펫은 Vue 패키지에서 `reactive` 함수를 가져오는 것으로 시작합니다. 그런 다음 `useFormValidation()` 함수를 생성하고 export합니다. 이 함수는 `formData`와 `formErrors` 속성을 포함하는 `reactive` 변수인 `state`를 생성합니다. `validateForm` 함수는 믹스인과 매우 유사한 방식으로 폼 유효성 검사를 처리하며, 마지막으로 `state` 변수와 `validateForm` 함수를 객체로 반환합니다.
컴포넌트 파일에서 이 자바스크립트 함수를 가져와서 컴포저블을 사용할 수 있습니다.
<template> <div> <form @submit.prevent="submitForm"> <div> <label for="username">Username:</label> <input type="text" id="username" v-model="state.formData.username" /> <span class="error">{{ state.formErrors.username }}</span> </div> <div> <label for="password">Password:</label> <input type="password" id="password" v-model="state.formData.password" /> <span class="error">{{ state.formErrors.password }}</span> </div> <button type="submit">Submit</button> </form> </div> </template> <script setup> import { useFormValidation } from "./formValidation.js"; import { ref } from "vue"; const { state, validateForm } = useFormValidation(); const submitForm = () => { if (validateForm()) { alert("Form submitted successfully!"); } else { alert("Please correct the errors in the form."); } }; </script> <style> .error { color: red; } </style>
이 코드는 `useFormValidation` 컴포저블을 가져온 후 반환되는 JavaScript 객체의 구조를 비구조화하여 폼 유효성 검사를 계속 처리합니다. 제출된 폼이 성공했는지, 아니면 오류가 있는지 사용자에게 알립니다.
컴포저블은 새로운 믹스인입니다.
Vue 2에서 믹스인은 코드를 재사용하는 데 유용했지만, Vue 3에서는 컴포저블이 이러한 역할을 대체합니다. 컴포저블은 Vue.js 애플리케이션에서 로직을 재사용하는 데 있어 보다 구조적이고 유지 관리하기 쉬운 접근 방식을 제공하며, 이를 통해 Vue를 사용하여 확장 가능한 웹 앱을 보다 쉽게 구축할 수 있도록 합니다.