개발 도구 (Development Tools)/Vue

#4. Vue 3 고급 문법

BiCute 2023. 5. 31. 08:00
반응형

 

# Composition API

 

Vue 3에서 새롭게 도입된 Composition API는 Vue.js의 고급 기능 중 하나로, Options API와 달리 코드의 구조화와 재사용성을 높일 수 있습니다.

Composition API는 Vue.js의 함수형 프로그래밍과 React Hooks와 같은 아이디어를 결합하여, 컴포넌트 로직을 보다 작고 독립적인 단위로 분리할 수 있습니다.

아래는 Composition API를 사용하여 구현된 간단한 Counter 애플리케이션 예시입니다.

<!-- Counter.vue -->
<template>
  <div>
    <h1>Counter: {{ counter }}</h1>
    <button @click="increment">Increment</button>
    <button @click="decrement">Decrement</button>
  </div>
</template>

<script>
import { reactive, toRefs } from "vue";

export default {
  setup() {
    const state = reactive({
      counter: 0
    });

    const increment = () => {
      state.counter++;
    };

    const decrement = () => {
      state.counter--;
    };

    return { ...toRefs(state), increment, decrement };
  }
};
</script>

위 코드에서는 reactive 함수를 사용하여 state 객체를 생성하고, toRefs 함수를 사용하여 state 객체를 reactive한 ref 객체로 변환합니다. 이후 incrementdecrement 함수를 정의하고, return 문에서 ref 객체와 함수를 합쳐서 반환합니다.

 

Composition API를 사용하면, Options API보다 더욱 직관적이고 간결한 코드를 작성할 수 있으며, 기능 단위별로 코드를 분리하여 재사용성을 높일 수 있습니다. 또한, reactive, ref, computed, watch 등의 함수를 사용하여 상태와 동작을 정의하므로, 코드의 가독성과 유지보수성을 향상시킬 수 있습니다.

 

 

 

# Teleport

 

Vue.js 3에서 도입된 Teleport는 컴포넌트를 DOM의 특정 위치로 이동시키는 기능을 제공합니다. 이 기능은 모달, 드롭다운, 툴팁 등의 UI 컴포넌트에서 유용하게 사용될 수 있습니다.

 

Teleport를 사용하면, 하위 컴포넌트에서 생성된 DOM 요소를 상위 컴포넌트의 특정 위치로 이동시킬 수 있으며, 이때 하위 컴포넌트는 이전의 위치와 상태를 유지합니다.


아래는 Teleport를 사용하여 모달 창을 구현한 간단한 예시입니다.

<!-- App.vue -->
<template>
  <div>
    <button @click="showModal = true">Show Modal</button>

    <teleport to="#modal">
      <div v-if="showModal" class="modal">
        <h1>Modal Title</h1>
        <p>Modal Content</p>
        <button @click="showModal = false">Close Modal</button>
      </div>
    </teleport>

    <div id="modal"></div>
  </div>
</template>

<script>
import { ref } from "vue";

export default {
  setup() {
    const showModal = ref(false);

    return { showModal };
  }
};
</script>

<style>
.modal {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background-color: white;
  padding: 20px;
}
</style>

위 코드에서는 Teleport를 사용하여 모달 컴포넌트를 #modal 위치로 이동시킵니다. 이때, teleport 태그에 to 속성으로 이동시킬 위치를 지정합니다.

 

모달 컴포넌트는 v-if 디렉티브를 사용하여 showModal 변수에 따라 표시되거나 숨겨집니다. 이때, 모달 컴포넌트는 Teleport를 사용하여 이전 위치와 상태를 유지한 채 #modal 위치로 이동됩니다.

 

Teleport를 사용하면, Vue.js의 컴포넌트 기반 설계와 함께 UI 컴포넌트를 더욱 유연하게 구현할 수 있습니다.

 

 

 

# Suspense

 

Vue.js 3에서 도입된 Suspense는 비동기 컴포넌트를 사용할 때, 로딩 상태를 렌더링할 수 있는 기능을 제공합니다. 이 기능을 사용하면, 코드 스플리팅과 같은 최적화 기법을 사용하여 앱의 초기 로딩 속도를 향상시킬 수 있습니다.

Suspense는 템플릿 내부에서 fallback 영역을 지정하여 로딩 상태를 표시하고, 비동기 컴포넌트가 준비되면 해당 컴포넌트를 렌더링하는 방식으로 동작합니다.

아래는 Suspense를 사용하여 비동기 컴포넌트를 로딩하는 예시입니다.

<!-- App.vue -->
<template>
  <div>
    <suspense>
      <template #default>
        <AsyncComponent />
      </template>

      <template #fallback>
        <p>Loading...</p>
      </template>
    </suspense>
  </div>
</template>

<script>
const AsyncComponent = () => import("./AsyncComponent.vue");

export default {
  components: {
    AsyncComponent
  }
};
</script>

위 코드에서는 suspense 태그로 비동기 컴포넌트를 래핑합니다. 이때, fallback 영역을 템플릿으로 지정하여 로딩 상태를 표시합니다. 비동기 컴포넌트는 import 함수를 사용하여 동적으로 로딩됩니다.

 

Suspense를 사용하면, Vue.js의 컴포넌트 기반 설계와 함께 비동기 컴포넌트를 더욱 쉽게 구현할 수 있습니다. 이를 통해 초기 로딩 속도를 향상시키는 등 앱의 성능을 최적화할 수 있습니다.

 

 

 

# Reactive와 Ref

 

  • Reactive

 

Vue.js 3에서 도입된 Reactive는 Vue.js의 반응성 시스템을 활용하여, 객체나 배열의 상태를 추적하고 업데이트할 수 있도록 하는 기능입니다.

 

Reactive는 ref, reactive, computed, watch와 함께 사용하여 데이터의 상태 변화를 감지하고 이를 뷰에 반영할 수 있습니다. 이를 통해 데이터와 뷰가 실시간으로 동기화되어, 뷰의 상태 변화를 쉽게 관리할 수 있습니다.

아래는 Reactive를 사용하여 객체의 상태를 추적하는 예시입니다.

<!-- App.vue -->
<template>
  <div>
    <p>{{ user.name }}</p>
    <p>{{ user.age }}</p>
    <button @click="incrementAge">Increment Age</button>
  </div>
</template>

<script>
import { reactive } from "vue";

export default {
  setup() {
    const user = reactive({
      name: "Alice",
      age: 25
    });

    const incrementAge = () => {
      user.age++;
    };

    return { user, incrementAge };
  }
};
</script>

위 코드에서는 reactive 함수를 사용하여 user 객체를 생성하고, nameage 속성을 추가합니다. 이후 incrementAge 함수를 정의하고, return 문에서 user 객체와 함수를 반환합니다.

 

user 객체의 속성은 반응성을 가지며, incrementAge 함수에서 user.age++와 같이 속성을 수정하면 해당 속성이 변경되고 이를 사용하는 뷰에 자동으로 반영됩니다.

 

Reactive를 사용하면, Vue.js의 반응성 시스템을 활용하여 데이터와 뷰를 더욱 효율적으로 관리할 수 있습니다. 이를 통해 코드의 가독성과 유지보수성을 높일 수 있습니다.

 

 

  • Ref

 

Vue.js 3에서 도입된 Ref는 객체의 속성을 추적하고 수정할 수 있도록 하는 기능입니다. Refreactive와 함께 사용되어, 반응성 있는 데이터를 관리하는 데 유용하게 사용됩니다.

Ref를 사용하면, 객체의 속성을 직접 수정할 수 있으며, 이때 속성 변경이 감지되어 뷰에 자동으로 반영됩니다. 또한, Ref를 사용하여 Vue.js의 반응성 시스템을 우회하여 기본 타입 변수를 관리할 수도 있습니다.

아래는 Ref를 사용하여 숫자를 관리하는 예시입니다.

<!-- App.vue -->
<template>
  <div>
    <p>{{ count }}</p>
    <button @click="increment">Increment</button>
  </div>
</template>

<script>
import { ref } from "vue";

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

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

    return { count, increment };
  }
};
</script>

위 코드에서는 ref 함수를 사용하여 count 변수를 생성합니다. count 변수의 초기값은 0으로 설정됩니다.

 

increment 함수에서는 count.value를 사용하여 count 변수의 값을 증가시킵니다.

이때, count.value는 Ref 객체의 속성으로, count 변수가 가리키는 Ref 객체의 값을 반환합니다.

 

Ref를 사용하면, Vue.js의 반응성 시스템을 활용하여 데이터와 뷰를 더욱 효율적으로 관리할 수 있습니다.

또한, Ref를 사용하여 기본 타입 변수를 관리하면, Vue.js의 반응성 시스템을 우회하여 성능을 향상시킬 수 있습니다.

 

 

reactive와 Ref의 차이점, 어떤것을 사용하면 좋은가

 

reactiveref는 모두 Vue.js 3에서 도입된 반응성 시스템을 사용하기 위한 함수입니다.

그러나 두 함수는 다른 방식으로 동작하며, 사용하는 시기와 용도가 다릅니다.

 

reactive는 객체 또는 배열을 반응성 데이터로 변환합니다.

reactive로 생성한 객체의 속성은 반응성을 가지며, 객체의 속성이 변경될 때 Vue.js의 반응성 시스템을 통해 뷰를 업데이트합니다. 이 때, reactive로 생성된 데이터 객체는 ref 함수를 사용하여 생성된 변수와 달리 .value 프로퍼티를 사용하지 않습니다.

 

반면, ref 함수는 기본 타입 변수를 반응성 데이터로 변환합니다. ref로 생성한 변수는 .value 프로퍼티를 사용하여 변수의 값을 읽거나 수정할 수 있습니다. ref로 생성한 변수는 reactive 함수를 사용하여 생성한 객체와 달리 Vue.js의 반응성 시스템과 함께 사용할 수 없으며, reactive 함수를 사용하여 객체나 배열을 생성할 때는 ref 함수를 사용하여 기본 타입 변수를 생성하는 것이 일반적입니다.

 

따라서, 객체나 배열과 같은 참조 타입의 데이터를 반응성 데이터로 관리할 때reactive 함수를, 기본 타입 변수를 반응성 데이터로 관리할 때ref 함수를 사용하는 것이 좋습니다.

 

 

 

# ToRefs

 

toRefs는 Vue 3의 Composition API에서 사용되는 함수 중 하나로, 객체를 받아 객체의 프로퍼티들을 각각 ref 객체로 만들어 리턴해줍니다.

toRefs 함수를 사용하면, reactive 객체에서 프로퍼티를 추출하여 각각의 ref 객체로 만들 수 있습니다. 이렇게 생성된 ref 객체들은 이전에 설명한 것과 같이 .value를 사용하여 접근해야합니다.

아래는 toRefs를 사용하는 예시입니다:

import { toRefs, reactive } from 'vue';

const state = reactive({
  person: {
    firstName: 'John',
    lastName: 'Doe',
    age: 30
  }
});

const refs = toRefs(state.person);

console.log(refs.firstName.value); // John
console.log(refs.lastName.value); // Doe
console.log(refs.age.value); // 30

위 코드에서 toRefs 함수는 person 객체를 받아서, firstNamelastNameage 속성을 ref 객체로 분해합니다. 

이렇게 분해한 ref 객체들을 refs 객체에 저장한 후, 템플릿에서 refs.firstName, refs.lastName, refs.age와 같이 사용할 수 있습니다.

 

 

 

Watch

 

watch 함수는 reactive 객체나 ref 객체의 변화를 감시하고, 변화가 감지되면 지정된 콜백 함수를 실행하는 함수입니다.

 

watch 함수는 다양한 형태의 인수를 받을 수 있습니다. 가장 간단한 형태는 watch(source, callback, options)입니다. source는 감시 대상이 되는 reactive 객체나 ref 객체를 지정하고, callback은 속성 값이 변경될 때 실행되는 콜백 함수를 지정합니다. optionswatch 함수의 동작을 설정하는 객체입니다.

 

아래는 watch 함수를 사용한 예시입니다.

<template>
  <div>
    <p>Count: {{ count }}</p>
    <button @click="incrementCount">Increment</button>
  </div>
</template>

<script>
import { ref, watch } from "vue";

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

    const incrementCount = () => {
      count.value++;
    };

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

    return { count, incrementCount };
  }
};
</script>

위 코드에서는 ref 함수를 사용하여 count 변수를 생성하고, 초깃값을 0으로 설정합니다. incrementCount 함수에서는 count.value1 증가시킵니다.

 

watch 함수에서는 count 변수를 감시하며, 값이 변경될 때마다 콜백 함수가 실행됩니다.

콜백 함수에서는 변경된 값과 이전 값이 인자로 전달됩니다. 콜백 함수에서는 이전 값과 변경된 값의 차이를 이용하여 필요한 로직을 처리할 수 있습니다.

 

위 코드에서는 간단히 변경된 값을 콘솔에 출력하는 예시를 보여주고 있습니다.

watch 함수는 ref 객체나 reactive 객체에서 속성 값의 변경을 감지하고, 해당하는 로직을 수행할 때 유용하게 사용할 수 있습니다.

 

아래는 watch 함수를 사용한 또다른 예시입니다:

const count = ref(0);

const handleCountChange = (newVal, oldVal) => {
  console.log(`count changed: ${oldVal} -> ${newVal}`);
};

watch(
  // 첫 번째 인수: 감시할 대상
  count,
  // 두 번째 인수: 대상이 변화할때 실행할 콜백 함수
  handleCountChange
);

위 코드에서는 count 변수를 ref 함수를 사용하여 생성하고, handleCountChange 함수를 정의한 후, watch 함수에서 감시 대상으로 count 변수를 전달하였습니다. 이때, watch 함수에서는 감시 대상을 첫 번째 인수로, 콜백 함수를 두 번째 인수로 전달하였습니다.

 

따라서, count 변수의 값이 변경될 때마다 handleCountChange 함수가 실행되며, 콘솔에는 count 변수의 이전 값과 최신 값을 출력합니다. 이와 같이 Composition API에서도 watch 함수를 사용하여 감시 대상을 지정하고, 변경 시 실행할 콜백 함수를 등록할 수 있습니다.

 

 

 

반응형