사용자 인터페이스(UI)를 개발하기 위한 자바스크립트 프레임워크로 Evan You 에 의해 개발 되었다.
React에 이어 2번째로 대중적인 프론트엔드 자바스크립트 프레임워크이며 React에 비해 러닝커브가 낮고 직관적인 문법, 뛰어난 성능, 높은 사용자 경험 등으로 개발자들 사이에서 인기 있는 프레임워크이다.
앞서 설명한 React 와 다르게 프레임워크이므로 어플리케이션 구성에 필요한 요소들을 자체적으로 제공한다.
예를 들어 React는 전역 상태 관리를 위해 Redux
, Recoil
, Zustand
등 추가 라이브러리를 설치해야 하지만 Vue는 자체적으로 상태관리 도구인 Vue jsx를 제공한다.
기존 렌더링의 경우, 화면에 변화가 생기면 모든 요소의 스타일을 다시 계산해 새로 그려주었는데
Vue는 가상DOM을 사용해 변경된 부분만 실제DOM에 그려주기 때문에 효율적이다. ✨
최초 렌더링에서는 Diffing
과정을 거치진 않지만 Virtual DOM을 먼저 만들고 실제 DOM으로 변환한다.
2-1-1. Vue 인스턴스 생성 및 앱 마운트
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
createApp(App)
으로 Vue 앱을 생성하고, .mount('#app')
을 통해 HTML의 특정 요소(div#app)에 앱을 연결한다.
2-1-2. 컴포넌트 초기화
루트 컴포넌트인 <App />
부터 시작해서 하위 컴포넌트들을 트리 구조로 재귀적으로 초기화 한다.
2-1-3. 템플릿을 렌더 함수로 컴파일
.vue
파일의 <template>
내용을 내부적으로 JavaScript의 redner() 함수로 컴파일 한다.
// Before
<template>
<p>{{ message }}</p>
</template>
// After
render() {
return h('p', null, this.message)
}
2-1-4. VNode(Virtual DOM Node) 트리 생성
render()
함수는 가상의 DOM 구조인 VNode 트리를 생성한다.
이 트리는 실제 DOM을 직접 조작하지 않고 메모리 상에 있는 가벼운 객체 트리이다.
2-1-5. VNode → 실제 DOM 변환 (Mount)
생성된 VNode 를 실제 브라우저 DOM으로 변환한다.
이 과정을 마운트
라고 부르며, 실제 html 요소가 만들어져 #app
에 삽입된다.
// html element
<div id="app">
<p>Hello Vue!</p>
</div>
2-1-6. DOM 삽입 후 mounted 훅 실행
렌더링이 완료되면, 컴포넌트의 mounted()
훅이 호출된다.
이 때부터 DOM 접근이 가능해진다.
mounted() {
console.log('컴포넌트가 마운트되었습니다!');
}
상태가 변경되면 Vue의 반응형 시스템
이 이를 감지하고 리렌더링 시킴
2-2-1. 변경된 데이터와 연결된 컴포넌트 찾기
Vue는 어떤 데이터가 어떤 컴포넌트에서 아용되는지 추적하고 있기 때문에
데이터가 사용된 템플릿/컴포넌트만 리렌더링 대상으로 지정한다.
2-2-2. 새로운 Virtual DOM(VNode) 트리 생성
변경된 데이터를 기준으로 새 render()
함수가 실행되며, 새로운 VNode
가 생성된다.
2-2-3. 이전 VNode와 비교 (Diffing)
이전에 만들어 놓은 VNode와 새로운 VNode를 비교해서 변경된 부분을 찾아낸다.
example)
- <p>Count: 0</p>
+ <p>Count: 1</p>
2-2-4. 실제 DOM 업데이트 (Patch)
변경된 부분만 실제 DOM에 적용한다.
☝🏻 컴파일
Vue의 템플릿은 렌더 함수
로 컴파일 된다.
렌더함수는 Virtual DOM 트리를 반환하는 함수이며 빌드 단계에서 수행할 수 있고, 런타임 컴파일러를 사용해 실시간으로 수행할 수 있다.(리렌더링)
✌🏻 마운트
런타임 렌더러가 렌더 함수의 호출 결과물인 Virtual DOM 트리를 순회하고, 실제 DOM 노드를 생성.
반응형 의존성 데이터들을 추적 시작.
🤟🏻 패치
마운트 시 사용된 의존성이 변경되면, Virtual DOM을 새로 생성하고 Diffing 과정을 통해 실제 DOM을 업데이트 시킨다.
웹 어플리케이션의 복잡한 UI를 재사용 가능한 단위로 분할하는 방식을 말한다.
각각의 컴포넌트는 자체적으로 상태와 속성을 가지고 있으며 독립적으로 존재한다.
이는 UI를 계층적으로 구조화하여 코드의 가독성을 높이고 유지보수를 용이하게 할 수 있다.
컴포넌트 개발 시, 구성요소 간의 의존성을 최소화 시켜야 복잡도가 낮고 재사용성을 높일 수 있는 장점이 있다. 😀
Vue의 <template>
영역은 기존 HTML과 거의 똑같은 구조로 작성할 수 있어
입문자들도 어렵지않게 UI를 구성할 수 있다.
// example.vue
<template>
<div>
<h1>안녕하세요, {{ name }}님!</h1>
<input v-model="name" placeholder="이름을 입력하세요" />
</div>
</template>
기존 HTML을 다뤄본 개발자라면 Vue 템플릿도 쉽게 이해할 수 있다. 😀
.vue
파일에 <template>
, <script>
, <style>
이 분리된 직관적인 구조이다.
<!-- HelloWorld.vue -->
<template>
<h2>안녕하세요, {{ user }}</h2>
</template>
<script>
export default {
data() {
return {
user: 'Vue 초보자'
};
}
}
</script>
<style scoped>
h2 {
color: teal;
}
</style>