Vue는 현재 국내에서 가장 많이 사용되는 프론트엔드 프레임워크 중 하나이다. Angular나 React와 비교했을 때 진입 장벽이 낮고 빠르게 제품을 만들 수 있다는 점이 큰 장점이다.
세 가지 프레임워크 모두 SPA(Single Page Application) 구조를 기반으로 하며, 데이터 바인딩, 이벤트 처리, 라우팅, 컴포넌트 등 유사한 개념을 공유한다.
SPA 동작 방식
단일 페이지 애플리케이션은 하나의 템플릿 페이지를 기반으로 동작한다.<router-view> 영역만 동적으로 교체되고 나머지 레이아웃은 유지된다. 최초 로뭉 시 페이지 파일을 받아오면 이후에는 데이터 통신만 이루어진다. 관리 시스템에서 흔히 보는 좌측 고정 네비게이션과 우측 변화하는 콘텐츠 영역이 대표적인 예시다. 이는 과거 JSP 방식과 대조적이다—JSP는 페이지 전환마다 서버로부터 전체 HTML을 새로 받아왔다.
Vue CLI 프로젝트 생성
Vue 생태계에서는 Vue CLI를 통해 프로젝트를 구성한다. 생성되는 디렉터리 구조는 수많은 실무 현장에서 검증된 관례(convention)이므로 따르는 것이 바람직하다.인스턴스 생성과 수동 마운트
Vue는 인스턴스 중심 설계를 따른다. 다음 두 가지 방식은 동일한 결과를 낳는다:// 방식 1: 축약 문법
new Vue({
render: fn => fn(Root),
}).$mount('#root')
// 방식 2: 전체 속성 명시
import Root from './Root'
new Vue({
el: '#root',
template: '<Root />',
components: { Root }
})
$mount 메서드는 지연 마운트가 필요할 때 유용하다. el 속성을 생략하고 추후 vm.$mount()를 호출하면 원하는 시점에 DOM에 부착할 수 있다.
컴포넌트와 Vue 인스턴스의 관계
컴포넌트는 재사용 가능한 Vue 인스턴스이다. 따라서data, computed, watch, methods, 라이프사이클 훅 등 동일한 옵션을 받는다. 단, el처럼 루트 인스턴스 전용 옵션은 예외이다.
핵심 의존성 구성
package.json를 살펴보면 Vue 생태계의 모듈화된 설계를 확인할 수 있다:
"dependencies": {
"axios": "^0.20.0",
"core-js": "^3.6.5",
"vue": "^2.6.11",
"vue-router": "^3.4.3",
"vuex": "^3.5.1"
}
라우팅이나 상태 관리가 필요하면 vue-router, vuex를 별도 추가해야 한다. 이는 Vue의 점진적 채택(Progressive Adoption) 철학을 반영한다—기존 프로젝트의 일부분만 Vue로 교체하는 것도 가능하다. 반면 Angular는 완전한 솔루션(Full Framework)으로 제공되어 이런 유연성은 상대적으로 떨어진다.
.vue 파일의 본질
.vue 확장자 파일은 SFC(Single File Component)로, HTML이나 JSP와는 다른 Vue 전용 형식이다. 빌드 과정에서 vue-loader가 이를 자바스크립트로 변환한다.
컴포넌트 사용 흐름은 다음과 같다:
- 정의:
const MyComp = Vue.extend({ ... }) - 전역 등록:
Vue.component('my-comp', MyComp) - 플릿 사용:
<my-comp />
Vue Router 설정 예시
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 라우트 대상 컴포넌트
const Home = { template: '<div>홈</div>' }
const About = { template: '<div>소개</div>' }
// 경로-컴포넌트 매핑
const routeTable = [
{ path: '/', component: Home },
{ path: '/about', component: About }
]
// 라우터 인스턴스 생성
const pageRouter = new VueRouter({
routes: routeTable
})
// 루트 인스턴스에 주입
new Vue({
router: pageRouter
}).$mount('#app')
주의할 점은 router 속성명이 고정되어 있다는 것이다. routers나 Router 등으로 변경하면 정상 동작하지 않는다.