vue의 기본
vue는 한 파일안에서 스크립트, 마크업, 스타일을 작성할 수 있는 SFC(single file component) .vue
문법을 지원한다.
즉, HTML
, CSS
,JavaScript
를 하나로 합친 셈이다.
내부에 있는 블록들은 컴포넌트의 뷰, 로직, 및 스타일을 캡슐화해서 배치한다.
다음은 간단한 SFC 구조다.
<script>
export default {
data() {
return {
greeting: '안녕 Vue!'
}
}
}
</script>
<template>
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
Vue는 기본적으로 컴포넌트 모듈을 객체
형태로 선언하며 props 정의, data
, methods
, 라이프사이클(mounted, updated, beforeUnmount, …), computed
, watch
등의 기능을 객체의 속성과 메소드를 사용해서 선언한다.
이와 같은 방식을 Option API라고 부르는데, 속성별로 역할과 책임이 분명히 나눠져 있다는 점에서
컴포넌트가 어떻게 동작하는지 이해하는 데 도움을 준다.
하지만, Option API는 프로젝트 규모가 커지거나, 폴더내에 있는 코드가 길어질 수록 극명하게 드러난다.
위에서 설명한 data, method, computed, watch등은 서로 연결되어 있는 경우가 있어서, 하나의 기능을 여러군대로 분산시켜 작성해야한다.
즉, 한 기능을 이해하기 위해서 이리저리 눈길을 옮겨야하는 경우가 생긴다.
이런 불편함을 없애기 위해, Composition API
라는 것이 vue3에서 새롭게 나타났다.
둘의 차이를 이해하기 위해서 다음 그림을 살펴보자.Option
에선 한 기능을 구현하기 위해서, 이리저리 옮겨가며 각자 역할에 맞는 부분에 작성해야한다.
그러니, 해당 기능을 이해하기 위해선 파편화된 코드를 이리저리 조합해야하는 불편함이 생긴다.
그러나 반면 Composition API
를 사용하게 된다면, 기능 중심으로 코드를 묶어둘 수 있기 때문에
해당 기능을 이해하기 위해서 이리저리 눈을 옮길 필요가 없는 것이다.
컴포지션 API
- 컴포지션(Composition) API는 옵션을 선언하는 대신 import한 함수를 사용하여 Vue 컴포넌트를 작성할 수 있는 API 세트입니다. -
Vue3 공식문서
공식문서에 따르면, 반복되는 로직을 추출해서 재사용할 수 있게 도와주고 그로 인해 유지보수와 성능을 보장받을 수 있다고 설명한다.
setup()
기본적으로 vue2의 option API 방식에선 다음과 같이 username
을 출력할 수 있었다.data
구문 내에 return
을 객체 형태로 다루면 template
에서 사용할 수 있다.
이 경우 vue 자체에서 data에 반응성을 가지게 된다.
<template>
{{ username }}
<template/>
<script>
export default {
data() {
return {
username : 'young'
}
}
<script/>
여기서 setup을 적용하게 되면 다음과 같이 구성할 수 있게 된다.
그러나 그냥 사용하게 된다면, setup에서 다루는 데이터는 반응성을 가지지 못하게 된다.
이럴 경우, 데이터가 변하게 되더라도 vue에서 이를 감지할 수 없게 된다.
<template>
{{ state.username }}
{{isHandsome}}
<template/>
<script>
export default {
setup(){
const isHandsome = ref(false)
const state = reactive({
username : 'young',
})
return {
state,
isHandsome
}
}
}
<script/>
이때, ref
나 reactive
를 적용해 반응형 변수를 만들 수 있다.
리액트의 useState와 비슷한 방식으로 작동한다 생각하면 이해가 쉽다.
- ref
- 반응성을 가진 변수를 만들 수 있다.
- reactive
- 반응성을 가진 객체를 만들 수 있다.
여기서 isHandsome을 콘솔로 찍어보면, 하나의 객체가 나오는 것을 볼 수 있다.
그리고 일반적인 Js 문법으로 methods
를 대체할 수 있다. 라이프사이클 메서드는 onMounted
, onUpdated
와 같은 라이프사이클 훅이 대체한다.
즉, option API
에선 컴포넌트 객체의 속성으로 분리되어 있던 기능을Composition API
에선 한 곳에서 관리할 수 있게 도와주는 것이다.
다음은 컴포지션 API를 사용한 컴포넌트의 기본 예다.
<script setup>
import { ref, onMounted, reactive } from 'vue'
// 반응형 상태
const count = ref(0)
const state = reactive({
username : 'young',
age : 24
})
// 상태를 변경하고 업데이트를 트리거하는 함수
function increment() {
count.value++
}
// 수명주기 훅
onMounted(() => {
console.log(`숫자를 세기 위한 초기값은 ${count.value} 입니다.`)
})
</script>
<template>
<button @click="increment">숫자 세기: {{ count }}</button>
</template>
여기서 중요한 점은, setup은 컴포넌트의 인스턴스가 생성되기 이전
에 실행된다.
즉, vue2의 beforeCreate
와 같은 시점에 실행되기에,
그리고 인스턴스가 생성된 직후에 호출되는 created
메소드에 매칭되는 라이프사이클 훅도 존재하지 않는다.
자연스럽게 컴포넌트 인스턴스 접근이 필요한 기능은 사용할 수 없다.
setup에 대해서
setup은 기본적으로 2가지 인자를 받는다.
- props
- context
Props
표준 컴포넌트에서 예상하는 것처럼 setup 내부의 props는 반응성이 있고, 새로운 props가 전달되면 업데이트된다.
Context
context는 3가지 컴포넌트 프로퍼티를 가지는 일반 JavaScript 객체다.
일반적인 객체라서 반응성이 존재하지 않고, 구조분해할당을 안전하게 사용할 수 있다.
setup 문법
vue3에서 혁신적인 변화로 꼽히지만, 아쉬운 점은 있기 마련이다.data
, methods
와 마찬가지로 return 을 사용해서 템플릿으로 값을 넘기는 과정이 필요하다는 것이다.
자꾸 react와 비교하게 되지만, react는 함수형 컴포넌트에서 상태 변수, 메서드를 선언한 후 JSX안에서 바로 사용이 가능하다.
그러나 setup은 변수나 메서드를 만들고 리턴을 해줘야한다.
import만 해도 바로 사용이 가능한 react에 비해서 불편함이 있는게 사실이다.
vue에선 import후 별도의 반복 작업이 필요하게 되니까 말이다.
그래서 나온것이 <script setup>
이다
<script setup>
const msg = 'Hello!'
function log() {
console.log(msg)
}
</script>
<template>
<!-- 템플릿 안에서 바로 사용 가능 -->
<div @click="log">{{ msg }}</div>
</template>
script setup을 통해 코드를 줄일 수 있게 됐다.
return을 통해서 template에 명시적으로 전달하는 과정이 생략된 덕분이다.
왜 컴포지션을 사용하나?
- 코드의 재사용성
- 컴포지션의 가장 큰 장점은 효율적인 로직 재사용이 가능하다.
- vue2의 mixins은 변수 이름이 같으면 충돌이 날 수 있기 때문
- 유연한 코드 구성
- vue2의 사용자는 option을 이용해 조직화된 코드를 구성하길 선호할 수 있다.
- 그러나 단일 컴포넌트에서 한 기능을 이해하기 위해 코드를 점프(?)해가며 읽는 경우 가독성은 물론 제한이 생긴다.
- 컴포지션을 사용한다면, 기능별로 코드를 정리해둘 수 있기 때문에 유지보수 측면에서 좋다.
- 더 나은 타입 추론
- 적은 오버헤드와 프로덕션 번들
- 별도의 프록시 없이 script setup 내부에 선언된 변수에 직접 접근할 수 있다.
- 즉, return 하지 않아도 사용이 가능.
출처
'studyLog > vue3' 카테고리의 다른 글
Vue3 lifeCycle는 어떤 방식으로 동작할까? (0) | 2022.10.21 |
---|---|
vue3 authorization 구현하기 (navigation guards) (0) | 2022.10.20 |
vue3에서 vue-i18n 다국어 처리 적용하는 법 (0) | 2022.09.17 |