Vue.js

Vue.js는 browser UI를 state-driven model로 구성하기 위한 frontend framework다.[1] 이 페이지는 Vue API 목록이 아니라, Vue가 어떤 문제를 어떤 구조로 해결하는지 설명하는 root concept이다. 이 강의에서 Vue는 두 층 사이에 놓인다.

Web application execution model
- SPA/CSR: browser가 interaction과 rendering의 많은 부분을 맡는 실행 맥락

Vue framework model
- App bootstrapping: createApp(), mount()
- Component/template: state에서 UI를 선언하는 단위
- Reactivity: state change를 render/update와 연결하는 메커니즘
- Reactivity API: ref(), reactive()

SPA and CSR은 Vue 내부 개념이 아니라 Vue가 유용해지는 실행 맥락이다. Vue reactivity는 Vue 내부의 핵심 메커니즘이고, ref vs reactive는 그 메커니즘을 쓰는 API 선택 문제다.

DOM 조작에서 state 선언으로의 전환

Vue의 핵심은 DOM 조작을 직접 나열하는 방식에서, state와 template을 통해 UI를 선언하는 방식으로 사고를 바꾸는 것이다.

flowchart TD
  Need["Interactive browser UI"] --> Problem["Manual DOM update becomes repetitive"]
  Problem --> Vue["Vue framework model"]
  Vue --> Bootstrap["App bootstrapping
createApp + mount"]
  Vue --> Template["Component/template
UI as a function of state"]
  Vue --> Reactivity["Reactivity
track state changes"]
  Reactivity --> Update["DOM update"]
  Context["SPA/CSR"] -. "common execution context" .-> Vue

Source는 Vue를 UI와 SPA-style web application 개발을 위한 progressive frontend framework로 소개하고, declarative rendering과 reactivity를 통해 state 변화에 따른 DOM update를 돕는다고 설명한다.[1:1] Vue application을 createApp()으로 만들고 .mount()로 DOM에 연결하며, ref()와 reactive()를 reactive state API로 소개한다.[1:2]

왜 state-driven rendering인가

이 source에서 Vue를 가장 잘 설명하는 질문은 "Vue는 browser UI의 변경 문제를 어떻게 state-driven rendering 문제로 바꾸는가?"라고 볼 수 있다.

Vue의 각 요소는 같은 층의 개념이 아니다. createApp()과 .mount()는 시작 경계이고, component/template은 UI를 선언하는 단위이며, reactivity는 state와 DOM update를 연결하는 메커니즘이다. ref()와 reactive()는 reactivity를 사용할 때 state shape를 표현하는 API다. 따라서 Vue Wiki는 API별 나열보다 실행 맥락 -> framework model -> reactivity mechanism -> API choice 순서로 읽는 편이 낫다는 관점에서 구성했다.

이 위계를 흐리는 흔한 실수는 app bootstrapping, component/template, reactivity, API choice를 같은 중요도의 페이지로 과하게 쪼개거나, ref()와 reactive() 선택을 Vue 전체 모델보다 앞세우는 것이다.

Vue가 놓이는 맥락과 경계

Vue는 browser DOM, JavaScript state, event-driven interaction 위에서 동작하며, 왜 state를 바꾸면 UI가 갱신되는 방식이 직접 DOM 조작보다 유지보수하기 쉬운지를 설명한다. 이는 event handler마다 DOM node를 찾아 수동으로 수정하는 방식과 대비된다. Vue는 app bootstrapping, component/template model, reactivity model을 포함하며, Vue component 설계, Vue Router 기반 SPA, form/list/modal 같은 interactive UI에 쓰인다.

Vue.js는 SPA/CSR과 같은 개념이 아니다. Vue는 framework이고, SPA/CSR은 browser와 server가 rendering/navigation 책임을 나누는 execution model이다 — 이 둘을 같은 층의 개념으로 섞는 것은 흔한 혼동이다.

createApp()은 Vue app의 시작점이지만 Vue 전체의 중심 개념은 아니다. Component, directive, lifecycle은 입문 source 하나로 승격하지 않았고, 후속 source에서 관계 밀도와 근거가 확인된 뒤 독립 페이지로 유지했다.

메커니즘

  1. Browser가 page와 JavaScript bundle을 load한다.
  2. createApp()이 root component를 기준으로 Vue app instance를 만든다.
  3. .mount()가 Vue runtime을 DOM subtree에 연결한다.
  4. Component/template이 state에서 UI를 선언한다.
  5. Reactive state가 바뀌면 Vue가 dependency를 추적해 render/update를 수행한다.

절충점

Vue를 state-driven framework가 아니라 DOM helper처럼 사용하는 것도 흔한 실패 모드다 — 이 경우 위 두 비용은 그대로 감수하면서 장점은 놓치게 된다.

예시

화면 여러 곳에 같은 nickname이 표시된다면 각 DOM node를 직접 찾아 수정하지 않는다. nickname state를 하나 두고 template이 그 state를 읽게 한다. 사용자가 nickname을 바꾸면 state가 바뀌고, Vue reactivity가 그 state를 사용하는 UI를 갱신한다.

관련

출처

테스트 질문


  1. 01-1.Vuejs-intro.pdf — Vue를 progressive frontend framework로 소개, declarative rendering/reactivity, createApp()/.mount(), ref()/reactive() 소개 ↩︎ ↩︎ ↩︎