FRONTEND

Vue.js 에서 데이터를 다루는 다양한 방법

주니어발록 2024. 2. 18. 20:40

오늘은 Vue.js의 다양한 데이터 관리 기능을 상세히 살펴보고, 각 기능의 차이점을 명확히 이해하고자 정리하게 되었습니다. 이를 통해, 보다 효과적으로 데이터를 관리하고, 반응성을 향상시킬 수 있으면 좋겠습니다.

클래스 내 변수와 메서드 선언

Vue.js 프레임워크 내에서 데이터 관리와 메서드 정의는 주로 data와 methods 속성을 통해 이루어집니다. 이와 별개로, JavaScript의 클래스 내에 변수와 함수를 선언하여 Vue.js에서 사용하는 방법도 있지만, 이 두 접근법 사이에는 중요한 차이가 존재합니다. Vue.js 애플리케이션의 컨텍스트에서, 특히 Vue 컴포넌트를 클래스 스타일로 작성할 때, ES6 클래스를 사용할 수 있습니다. 이 경우, 컴포넌트의 데이터와 메서드는 클래스의 프로퍼티와 메서드로 정의됩니다.

이 클래스는 초기 메시지를 설정하고, 새 메시지로 업데이트하는 메서드를 제공합니다. Vue 컴포넌트에서 이 클래스를 사용하기 위해 다음과 같이 작성할 수 있습니다.

// MessageService.js
class MessageService {
  constructor() {
    this.message = 'Hello, Vue.js!';
  }

  reverseMessage() {
    this.message = this.message.split('').reverse().join('');
  }
}

 

MessageService 인스턴스의 message 프로퍼티 변경은 Vue의 반응형 시스템에 의해 자동으로 감지되지 않습니다. 따라서, message 프로퍼티가 변경되어도 뷰가 업데이트되지 않는 문제가 발생합니다.

<template>
  <div>
    <p>{{ messageService.message }}</p>
    <button @click="reverseMessage">Reverse Message</button>
  </div>
</template>

<script>
import MessageService from './MessageService';

export default {
  data() {
    return {
      messageService: new MessageService()
    };
  },
  methods: {
    reverseMessage() {
      this.messageService.reverseMessage();
      // 문제: Vue는 messageService.message의 변경을 감지하지 못함
    }
  }
}
</script>

$set 메서드 사용

Vue의 $set 메서드는 Vue의 반응형 시스템이 기본적으로 감지하지 못하는 변경사항(예: 객체에 새로운 속성을 추가할 때)을 반응형으로 만들 때 사용됩니다. 이 방법은 주로 다음과 같은 상황에서 유용합니다:

  • 동적 속성 추가: Vue 인스턴스 또는 data 객체에 동적으로 새로운 속성을 추가하고자 할 때.
  • 클래스 프로퍼티 업데이트: Vue의 반응형 시스템과 통합되지 않는 외부 클래스의 인스턴스 속성을 업데이트할 때.

$set을 사용하여 messageService.message의 변경사항을 Vue의 반응형 시스템에 등록함으로써, message 프로퍼티가 변경될 때 뷰가 적절히 업데이트되도록 할 수 있습니다.

methods: {
  reverseMessage() {
    this.messageService.reverseMessage();
    this.$set(this.messageService, 'message', this.messageService.message);
    // $set을 사용하여 message 프로퍼티 변경을 반응형으로 만들어 Vue가 감지할 수 있게 함
  }
}

data, methods 속성 사용

data와 methods 속성을 사용하는 전통적인 Vue.js 개발 방식은 Vue 인스턴스의 상태 관리와 로직 구현을 위한 권장된 접근법입니다.

MessageService 클래스의 인스턴스를 사용하지 않고, 컴포넌트의 data와 methods 속성을 직접 활용하여 동일한 기능을 구현합니다. Vue의 반응형 시스템이 data 속성의 변경을 자동으로 감지하므로, 추가적인 조치 없이도 UI가 적절히 업데이트됩니다.

<template>
  <div>
    <p>{{ message }}</p>
    <button @click="reverseMessage">Reverse Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello, Vue.js!'
    };
  },
  methods: {
    reverseMessage() {
      this.message = this.message.split('').reverse().join('');
      // 직접적으로 data 속성을 변경하여 Vue의 반응형 시스템이 변경을 감지하게 함
    }
  }
}
</script>

data 속성

Vue 인스턴스 내의 data 속성은 애플리케이션에서 사용할 모든 데이터를 저장하는 곳입니다. 이 속성은 객체를 반환하는 함수로 정의됩니다. 이는 Vue가 각 인스턴스 별로 독립적인 데이터 객체를 유지할 수 있습니다. 데이터 속성에 정의된 값은 인스턴스 내의 다른 속성(예: methods, computed) 및 템플릿에서 직접 접근할 수 있습니다.

data 함수는 message라는 속성을 포함하는 객체를 반환합니다. 이제 message 속성은 HTML 템플릿 내에서 {{ message }}를 통해 사용될 수 있습니다.

Vue.js에서는 데이터와 DOM이 반응형으로 연결됩니다. data 속성에 정의된 데이터가 변경되면 Vue가 자동으로 관련된 DOM을 업데이트합니다.

message의 값을 변경하면 Vue는 자동으로 DOM 내의 message를 표시하는 부분을 새로운 값으로 업데이트합니다. 가상 DOM은 실제 DOM에 적용하기 전에 변경사항을 효율적으로 계산할 수 있게 해주며, 이를 통해 Vue는 최소한의 DOM 조작으로 뷰를 업데이트할 수 있습니다. 

<template>
  <div id="app">
    <p>{{ message }}</p>
    <button @click="updateMessage">Update Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue!'
    }
  },
  methods: {
    updateMessage() {
      this.message = 'Hello Vue.js!'
    }
  }
}
</script>

Methods 속성

Vue.js의 methods 속성은 컴포넌트 내에서 사용할 함수들을 정의하는 곳입니다. 이 메서드들은 이벤트 핸들러나 데이터 처리 등을 위해 주로 사용되며, 템플릿 내에서 직접 호출될 수 있습니다. methods 속성을 사용함으로써, 복잡한 로직을 관리하고 재사용 가능한 코드를 작성할 수 있습니다.

methods 속성 내에서 함수를 정의하고, 이 함수들은 컴포넌트의 다른 데이터와 속성에 접근할 수 있습니다. 이벤트 바인딩을 통해 템플릿에서 이 메서드들을 호출할 수 있으며, 사용자 인터랙션에 반응하는 동적인 애플리케이션을 구축할 때 중요한 역할을 합니다.

methods와 computed는 모두 컴포넌트 내에서 로직을 처리하는 데 사용되지만, 그 목적과 사용 상황에는 차이가 있습니다. computed 속성은 종속된 데이터가 변경될 때만 다시 계산되며 결과를 캐시합니다. 이는 주로 데이터를 변환하거나 계산된 값을 필요로 할 때 사용됩니다. 반면, methods는 호출될 때마다 함수를 실행합니다. 이는 사용자의 액션에 반응하거나, 반복적이지 않은 로직을 실행할 때 주로 사용됩니다.

reverseMessage 메서드를 정의하여 버튼 클릭 이벤트에 반응합니다. 사용자가 버튼을 클릭하면 reverseMessage 메서드가 실행되어 message의 문자열 순서를 뒤집습니다. 이 경우, 메서드는 사용자의 직접적인 액션에 의해 호출되며, 호출될 때마다 message 문자열을 뒤집는 로직을 수행합니다. methods를 사용하는 이 방식은 사용자 인터랙션과 같이 동적인 애플리케이션의 기능을 구현할 때 매우 유용합니다. 사용자의 액션에 따라 다양한 데이터 처리와 로직 실행이 필요할 때 methods를 활용하여 이를 효과적으로 관리할 수 있습니다.

<template>
  <div id="app">
    <p>{{ message }}</p>
    <button @click="reverseMessage">Reverse Message</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue.js!'
    }
  },
  methods: {
    reverseMessage() {
      this.message = this.message.split('').reverse().join('');
    }
  }
}
</script>

 

Watchers

Vue.js에서 watch 속성은 컴포넌트 데이터의 변화를 감시하고, 해당 데이터가 변경될 때마다 특정 액션을 수행할 수 있도록 해주는 반응형 기능입니다. watch는 데이터의 변화를 감지하고, 복잡한 로직을 수행하거나, 비동기 연산(예: API 호출)을 실행할 때 사용합니다.

watch 속성은 객체 형태로, 감시하려는 데이터 항목의 이름을 키로, 해당 데이터가 변할 때 실행할 함수를 값으로 가집니다. 이 함수는 감시하고 있는 데이터의 새 값을 첫 번째 인자로, 이전 값을 두 번째 인자로 받습니다.

watch를 사용하면 데이터 항목의 변화에 따라 적절한 반응을 할 수 있습니다. 예를 들어, 사용자 입력이나 API로부터 받은 데이터가 특정 조건을 만족할 때 추가적인 처리를 할 수 있습니다. watch는 computed 속성과 달리, 데이터 변화에 대해 보다 복잡한 반응 로직을 구현할 때 주로 사용합니다.

userInput 데이터 항목을 감시하고 있습니다. 사용자가 입력 필드에 텍스트를 입력할 때마다, watch 속성에 정의된 userInput 함수가 호출되어 inputLength 데이터를 업데이트합니다. 이를 통해 사용자가 입력하는 텍스트의 길이를 실시간으로 표시할 수 있습니다. watch 속성은 데이터 변화에 따른 사이드 이펙트를 관리하거나, 비동기 연산을 수행하는 등의 복잡한 반응 로직을 구현할 때 매우 유용합니다. 특히, 데이터 변화에 따라 여러 단계의 처리가 필요한 경우에 watch를 활용하여 이를 효과적으로 구현할 수 있습니다.

<template>
  <div id="app">
    <input v-model="userInput" placeholder="Type something...">
    <p>Input Length: {{ inputLength }}</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userInput: '',
      inputLength: 0
    }
  },
  watch: {
    userInput(newVal, oldVal) {
      this.inputLength = newVal.length;
    }
  }
}
</script>

<style>
/* 컴포넌트 스타일 */
</style>

 

Computed 속성

computed 속성은 기존 데이터를 기반으로 새로운 값을 계산하여, 그 결과를 효율적으로 재사용할 수 있게 해주는 Vue.js의 기능입니다. 이러한 속성은 특히 계산이 필요한 값에 대해 반응형 데이터 바인딩을 제공합니다. computed 속성은 내부적으로 캐싱 메커니즘을 사용하기 때문에, 종속 대상이 변경되지 않는 한 계산된 값을 재사용합니다. 이는 성능 최적화 측면에서 큰 이점을 제공합니다.

computed 속성과 메서드는 비슷해 보일 수 있지만, 중요한 차이점이 있습니다. 메서드 호출은 호출될 때마다 함수를 실행합니다. 반면에, computed 속성은 종속성이 변경될 때만 함수를 실행하고, 그 결과를 캐시합니다. 따라서, 동일한 결과를 반복해서 사용해야 하는 경우 computed 속성이 더 효율적입니다.

reversedMessage는 message 데이터에 의존하는 computed 속성입니다. 사용자가 message 값을 변경할 때마다 reversedMessage가 자동으로 업데이트되지만, message가 변경되지 않는 한 reversedMessage의 값은 캐시된 결과를 반환합니다. 이로 인해 불필요한 계산을 줄이고, 애플리케이션의 렌더링 성능을 크게 향상시킬 수 있습니다. computed 속성을 사용함으로써, 데이터의 변화에 따라 자동으로 업데이트되는 동적이고 반응적인 UI를 효율적으로 구현할 수 있습니다. 이는 Vue.js 애플리케이션의 성능 최적화와 직결되는 부분으로, 복잡한 데이터 변환과 조작이 필요한 상황에서 특히 유용합니다.

<template>
  <div id="app">
    <p>Original Message: "{{ message }}"</p>
    <p>Reversed Message: "{{ reversedMessage }}"</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello Vue.js!'
    }
  },
  computed: {
    reversedMessage() {
      // 종속 대상 `message`가 변경될 때만 이 함수를 실행합니다.
      return this.message.split('').reverse().join('');
    }
  }
}
</script>

 

Getters와 Setters

JavaScript에서 get과 set 함수는 객체의 속성에 접근하기 위한 방법을 제공합니다. 이 기능을 통해 개발자는 객체 내부의 데이터에 대한 더 세밀한 접근 제어를 할 수 있으며, 이를 활용하여 데이터의 유효성 검사, 로깅, 내부 변수의 변경 등 복잡한 작업을 수행할 수 있습니다.

get 함수는 특정 속성의 값을 읽을 때 호출되며, set 함수는 속성에 값을 할당할 때 호출됩니다. 이들 함수를 사용하면, 직접 속성에 접근하는 것처럼 보이지만, 실제로는 함수를 통해 접근하게 됩니다. 이 방법은 객체 지향 프로그래밍에서 캡슐화와 정보 은닉의 원칙을 따르는 데 유용합니다.

Vue.js에서는 computed 속성을 통해 get과 set 함수를 사용할 수 있습니다. computed 속성은 기본적으로 getter 함수만을 가지고 있지만, 필요에 따라 setter 함수를 정의하여 복잡한 로직 처리에 활용할 수 있습니다. 이를 통해 데이터의 읽기와 쓰기를 동시에 제어할 수 있으며, 데이터 바인딩과 사용자 인터페이스의 상호작용을 더욱 효과적으로 관리할 수 있습니다.

Vue.js 2를 기반으로 computed 속성에서 get과 set 함수를 사용하는 예제 코드입니다. 이 예제에서는 사용자가 입력하는 메시지를 역순으로 저장하고 표시하는 간단한 기능을 구현합니다.

reversedMessage computed 속성은 get과 set 함수를 모두 정의하고 있습니다. 사용자가 입력 필드에 텍스트를 입력할 때, set 함수가 호출되어 입력 값을 역순으로 변환한 후 originalMessage에 저장합니다. 그리고 화면에는 get 함수를 통해 역순으로 변환된 메시지가 표시됩니다. 이 예제는 Vue.js에서 get과 set 함수를 활용하여 데이터의 읽기와 쓰기를 어떻게 제어할 수 있는지 보여줍니다. 이 방법을 통해 데이터 처리 로직을 더욱 유연하게 구성할 수 있으며, 사용자 인터페이스와의 상호작용을 효과적으로 관리할 수 있습니다.

<template>
  <div id="app">
    <input v-model="reversedMessage" placeholder="Type something...">
    <p>Original Message: "{{ originalMessage }}"</p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      originalMessage: ''
    }
  },
  computed: {
    reversedMessage: {
      // getter 함수
      get() {
        return this.originalMessage.split('').reverse().join('');
      },
      // setter 함수
      set(newValue) {
        this.originalMessage = newValue.split('').reverse().join('');
      }
    }
  }
}
</script>

 

클래스 스타일 바인딩과 데이터 처리

Vue.js에서 제공하는 데이터 바인딩 기능은 개발자가 웹 애플리케이션의 데이터와 UI 요소를 효율적으로 연결할 수 있게 해줍니다. 이 중에서 클래스 및 스타일 바인딩은 특히 UI의 동적인 변화를 데이터의 상태에 따라 관리할 수 있게 해주는 강력한 기능입니다. Vue.js의 이러한 바인딩 기능을 활용하면, 애플리케이션의 상태 변화를 사용자에게 직관적으로 전달할 수 있습니다.

 

클래스 바인딩

클래스 바인딩은 특정 HTML 요소의 클래스를 데이터의 상태에 따라 동적으로 추가하거나 제거할 수 있게 해줍니다. Vue에서는 v-bind:class (또는 축약형 :class) 디렉티브를 사용하여 이를 구현합니다. 클래스 바인딩에는 주로 객체 구문과 배열 구문의 두 가지 방식이 사용됩니다.

  • 객체 구문: 객체의 속성을 클래스 이름으로, 그 값(true 또는 false)을 해당 클래스의 적용 여부로 사용합니다. 이 방식은 조건부로 클래스를 추가할 때 유용합니다.
  • 배열 구문: 배열을 사용하여 여러 클래스를 동시에 적용할 수 있습니다. 이는 여러 조건에 따른 클래스를 유연하게 적용하고자 할 때 효과적입니다.

스타일 바인딩

스타일 바인딩은 v-bind:style (또는 축약형 :style) 디렉티브를 통해 인라인 스타일을 동적으로 바인딩합니다. 스타일 바인딩은 CSS 속성을 객체 구문이나 배열 구문을 사용하여 직접 지정할 수 있게 해줍니다.

  • 객체 구문: CSS 속성을 객체의 키로 사용하고, 값으로는 해당 속성에 적용할 스타일 값을 지정합니다. 이 방식은 복수의 스타일을 한 번에 적용할 때 효과적입니다.
  • 배열 구문: 여러 스타일 객체를 배열에 담아 요소에 적용할 있습니다. 이는 다양한 스타일 조건을 조합할 사용됩니다.

사용자의 액션에 따라 특정 HTML 요소의 클래스를 동적으로 변경하는 방법을 보여줍니다. 이 예제에서는 사용자가 버튼을 클릭할 때마다 메시지의 스타일이 변경되도록 구현하였습니다.

isSuccess와 isError라는 두 개의 데이터 속성을 사용하여 <p> 태그의 클래스를 조건부로 할당합니다. 사용자가 "Toggle Success" 버튼을 클릭하면 isSuccess 값이 토글되고, "Toggle Error" 버튼을 클릭하면 isError 값이 토글됩니다. 이에 따라 메시지의 텍스트 색상이 동적으로 변경됩니다. 이 예제는 Vue.js에서 데이터를 기반으로 클래스를 동적으로 할당하는 방법을 보여줍니다. 이를 통해 개발자는 애플리케이션의 상태 변화를 사용자에게 시각적으로 표현할 수 있으며, UI의 인터랙티브한 요소를 효과적으로 관리할 수 있습니다. 데이터와 클래스 바인딩 기능을 활용함으로써, 더 유연하고 반응성이 뛰어난 웹 애플리케이션을 구축할 수 있습니다.

<template>
  <div id="app">
    <p :class="{'text-success': isSuccess, 'text-error': isError}">{{ message }}</p>
    <button @click="toggleSuccess">Toggle Success</button>
    <button @click="toggleError">Toggle Error</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isSuccess: false,
      isError: false,
      message: 'Hello Vue.js!'
    }
  },
  methods: {
    toggleSuccess() {
      this.isSuccess = !this.isSuccess;
      this.isError = false; // Ensure only one class is active at a time
    },
    toggleError() {
      this.isError = !this.isError;
      this.isSuccess = false; // Ensure only one class is active at a time
    }
  }
}
</script>

<style>
.text-success {
  color: green;
}

.text-error {
  color: red;
}
</style>

 

결론

Vue.js에서 제공하는 다양한 데이터 관리 방법들은 개발 시 유연성을 제공해줍니다. 오늘 비교한 개념들을 정확히 이해하고 적합한 상황에서 사용하여 효율적은 웹서비스 개발에 도움이 되었으면 좋겠습니다. 

기능 설명 렌더링 데이터 변경 시 사용 예시
클래스 내 변수/함수
ES6 클래스 내에서 데이터와 메서드를 캡슐화 클래스 인스턴스 변경 시 직접적인 렌더링 영향 없음 Vue의 반응형 시스템과의 통합을 위해 특별한 처리 필요 코드 재사용성 및 구조화를 위한 고급 상태 관리 및 메서드 구현에 적합
data 컴포넌트의 반응형 데이터를 정의 직접적인 데이터 바인딩에 사용되며, 데이터 변경  자동 업데이트 초기 상태 정의에 사용, 데이터 변경  Vue 자동으로 DOM 업데이트 컴포넌트의 상태를 나타내는 기본적인 데이터 관리에 적합
computed 종속 대상을 기반으로 계산된 값을 캐싱 종속된 데이터가 변경될 때만 재계산되어 렌더링에 효율적 데이터 읽기 전용 또는 get/set 정의 가능, 종속 데이터 변경에만 반응 데이터 기반으로 계산해야 하는 값을 동적으로 관리할  사용
methods 컴포넌트에서 사용할 메서드 정의 메서드가 호출될 때마다 렌더링이 필요한 연산을 수행 호출될 때마다 메서드 실행, 캐싱되지 않음 이벤트 핸들링이나 반복되지 않는 연산에 적합
watchers 데이터 변화를 감시하고 변화  콜백 함수 실행 데이터 변경에 따라 복잡한 로직이나 비동기 작업을 수행할  있음 데이터 변경 감지에 사용, 보다 복잡한 반응 로직 구현에 적합 데이터 변화에 따른 사이드 이펙트 처리나 비동기 업데이트에 적합
get/set 컴퓨티드 속성 내에서 사용, 데이터 접근 제어와 복잡한 로직 수행 가능 직접적인 영향은 없으나, 데이터 접근 방식에 유연성 제공 데이터 읽기/쓰기 작업에 사용자 정의 로직 적용 가능 데이터 프로퍼티의 읽기/쓰기 작업을 제어해야   사용
클래스 스타일 바인딩 데이터 바인딩을 통해 동적으로 클래스나 스타일을 HTML 요소에 할당 조건부 스타일이나 클래스 적용으로 동적 UI 변경 가능 클래스나 스타일 변경은 데이터의 변화에 따라 이루어짐 UI 시각적 표현을 데이터 상태에 따라 변경해야   사용