[TIL] Vue - ref vs reactive

jeongjwon·2023년 12월 13일

Vue

목록 보기
2/19

Composition API

Vue 2 에는 Option api 가 주로 쓰였고, Composition api 도 있었지만, Vue 3 이후부터는 Composition API 를 쓸 것을 권장하고 있다.
기존의 Vue 는 프로젝트 규모가 커질수록 컴포넌트의 계층 구조가 복잡해지면서 추적 및 관리에 어려움이 있었다. 이런 단점을 커버하기 위해 Vue 3 부터는 Composition API 가 추가되었다.





1. 보다 유연한 코드 구성

Options API vs Composition API

Options APIComposition API
data, methods, computed 에 각각 로직이 흩어져 있다.data, methods, computed로 로직을 구성하지 않고 로직을 모아 사용할 수 있다. 또한, export default{ } 를 제공하지 않아서 일반적인 JavaScript 를 작성하는 것처럼 컴포넌트 코드를 작성할 수 있다.

물론 Options API를 이용해서 정해진 구조로, 개발자가 로직을 구성할 때 덜 복잡하게 도와줄 수 있지만, 그렇게 되면 다양성이 없어진 코드 구성 패턴 때문에 규모가 큰 프로젝트에서 리팩토링하거나 유지보수가 어려울 수 있다. 따라서 로직을 유연하게 구성할 수 있어서 코드의 재사용성과 가독성을 높이고, 장기적으로 더 크고 나은 확장성을 제공할 수 있다.



2. 더 나은 로직 재사용성

Composition API의 가장 큰 장점은 컴포저블 함수의 형태로 깔끔하고 효율적인 로직 재사용이 가능하다는 것이다. Options API의 기본 로직 재사용 매커니즘인 믹스인의 모든 단점을 해결한다.

💡 컴포저블 : Vue Compositon API를 활용하여 상태 저장 로직을 캡슐화하고 재사용하는 함수로 여러 컴포넌트에서 동일한 로직을 재사용하기 위해 컴포저블 함수로 재구성 후 외부 파일로 추출할 수 있다.

💡 믹스인 : Vue2 버전에서 컴포넌트에 재사용 가능한 기능을 배포하는 유연한 방법으로 mixins 옵션은 믹스인 객체로 이루어진 배열이다.



3. 더 작은 프로덕션 번들 및 더 적은 오버헤드

Composition API 와 <script setup> 으로 작성된 코드는 Options API 에 비해 더 효율적이고 축소하기 쉽다.
<script setup> 을 사용하면 별도로 데이터와 메서드를 선언할 필요가 없다. props를 자동 선언해주며, 컴포넌트 내부에서 레퍼런스를 명시적으로 선언할 필요없이 알아서 추론을 도와준다. 이런 이유로 Composition API와 자연스럽게 통합되어 코드의 일관성과 가독성이 향상될 수 있다.

💡 <script setup> : 싱글 파일 컴포넌트 (SFC) 내에서 Composition API 를 더 쉽게 읽거나 사용하기 위한 컴파일 문법이다. <script> 와 달리 내부의 코드는 컴포넌트의 인스턴스가 생성할 때 마다 실행된다.






반응형

반응형이란, 데이터가 변경되었을 때 이를 감지하고 반응하여 DOM이 자동으로 업데이트 되는 성질을 말한다. 다시 말해, 데이터가 변경되면 화면 UI 가 변경되는 것이고, 변경된 데이터 값을 렌더링 해주는 작업을 하지 않아도 된다.(반응형 상태)

이런 반응형 상태를 선언하기 위한 방법에는 ref 와 reactive 가 있다.



ref()

기본 타입을 반응형 상태로 선언하는데 사용한다.
반응하는 객체를 반환하며, 내부적으로 value 라는 단 하나의 속성만 포함하며 값은 매개변수로 받은 값을 저장한다.
객체 타입은 Primitive Type(number, string, boolean,,,)까지 모든 타입에 대한 반응성을 제공

<script>
const count = ref(0) //ref() 매개변수로 받은 값 = 0으로 저장
count.value++  // value 속성으로 접근
console.log(count.value) //1
</script>

reactive()

ref()와 다르게 객체나 배열 타입의 반응형 상태만을 선언하는데 사용된다. (ref 와 큰 차이점)
.value 를 생략하는 언래핑을 통해 접근 가능하다.
해당 객체의 프로퍼티가 변경될 때마다 자동으로 해당 변경 사항을 감지하여 뷰를 업데이트한다.

💡 래핑 : 어떤 값이 할당되어있다고 가정한다면, .value 를 통해 할당된 값에 접근하는 것
💡 언래핑 : .value 없이 접근 가능한 것

<script>
const state = reactive({
	count: 0 
})
console.log(state.count); //0
</script>






Proxy

변경 내용을 추적하는 방법(반응형 상태)는 바로 Proxy를 통해서이다.

Proxy는 특정 객체를 감싸 프로퍼티 읽기, 쓰기와 같은 객체에 가해지는 작업을 중간에서 가로채는 객체로, 가로채진 작업은 Proxy 자체에서 처리되기도 하고, 원래 객체가 처리하도록 그대로 전달되기도 한다.

JavaScript Object 를 생성하면 기본적으로 접근자 프로퍼티라고 하여 getter 와 setter 함수가 자동으로 포함된다. Proxy 를 통해 Object 의 get() 과 set() 메서드를 재정의하여 원하는 동작을 만들 수 있다. 이것이 바로 vue 반응성의 핵심이다.

다시말해, Vue 에서 반응형 상태 객체를 Proxy 객체로 만들어서 값이 바뀌는 동작이 일어나는 set() 메서드가 호출되고, set() 핸들러에서 DOM을 업데이트하는 동작을 시키는 것이다.

  1. getter 와 setter 는 속성에 접근 get 하거나 수정 set 할 때, Vue 가 종속성 추적 또는 변경 알림을 수행한다.
  2. 모든 컴포넌트 인스턴스에 해당 watcher 인스턴스가 있고, 이 인스턴스는 컴포넌트가 종속적으로 렌더링되는 동안 수정된 모든 것을 기록한다.
  3. 나중에 종속적인 setter 가 트리거가 되면 watcher에 전달하고 컴포넌트가 다시 렌더링된다.


Vue 는 DOM 업데이트를 비동기로 한다.
데이터 변경이 발견 될 때마다 큐를 열고 같은 이벤트 루프에서 발생하는 모든 데이터 변경을 버퍼에 담는다.
같은 Watcher 가 여러번 발생하면 대기열에서 한 번만 푸시된다.
이벤트 루프 "tick" 에서 Vue 는 대기열을 비우고 실제 (이미 중복 제거된) 작업을 수행한다.







마치며

Vue 공식 홈페이지의 빠른 시작의 예제를 풀어보며 컴포지션 api 를 사용하는 이유에 대해 더 알아보았다. 반응형 상태를 위해 ref 와 reactive 를 활용한다는 것도 알았다.
다음은 빠른 시작을 오답노트 한다는 의미로 포스팅 해보겠다.

0개의 댓글