Vue 템플릿은 가상 DOM을 반환하는 render 함수로 컴파일됩니다. 보통은 템플릿을 작성하지만, UI를 프로그래밍 방식으로 생성하기 위해 JavaScript의 완전한 힘이 필요할 때는 render 함수(또는 JSX)를 직접 작성할 수 있습니다.
render 함수
js
{ h } ;
{
: [],
() {
(, slots.());
},
};
h(tag, props, children)은 vnode를 명령형으로 구축합니다. 여기서 헤딩 레벨은 런타임에 계산되어 h1–h6을 선택합니다 — 템플릿 문법으로는 어색합니다.
export default {
props: ["items"],
setup(props) {
return () => (
<ul>
{props.items.map((item) =>
item.visible ? <li key={item.id}>{item.name}</li> : null
)}
</ul>
);
},
};
JSX는 일반 JS(.map, 조건문, 변수)로 트리를 구축하게 해줍니다 — React 개발자에게 친숙하고 매우 동적인 구조에 더 유연합니다.
✓ 프로그래밍 방식 구조: 런타임에 결정되는 태그/컴포넌트 (동적 헤딩, 스키마 기반 UI)
✓ v-if/v-for로 표현하기 어려운 고도로 조건적이거나 재귀적인 렌더링
✓ 재사용 가능한 컴포넌트 라이브러리 / 고차 컴포넌트(HOC) 구축
✓ 템플릿 디렉티브가 어색한, 복잡한 JS 로직 기반 렌더링
✓ 거의 모든 앱 UI — 템플릿은 더 읽기 쉽고, 컴파일러에 의해 최적화되며,
컴파일 타임 힌트(정적 호이스팅, patch flag)로 성능 이점을 얻음
✓ 더 나은 도구 지원: IDE 하이라이팅, 타입 검사, 팀 전체에 더 쉬움
특히 템플릿 컴파일러는 손으로 작성한 render 함수가 자동으로 얻지 못하는 성능 최적화(무엇이 정적이고 동적인지 앎)를 추가합니다.
템플릿은 올바른 기본값입니다 — 읽기 쉽고, 도구 친화적이며, 컴파일러 최적화됩니다.
하지만 render 함수/JSX는 UI가 프로그래밍 방식으로 생성되어야 할 때(동적 태그, 재귀 트리, 라이브러리 컴포넌트) 템플릿 문법이 뒤틀리는 경우의 탈출구입니다.
둘 다 존재한다는 것을 알고 — 일반적인 앱 코드에는 템플릿이 선호되고 동적/라이브러리 시나리오에는 render 함수가 적합하다는 것을 알면 — 한 가지 접근을 모든 곳에 강요하지 않고 올바른 도구를 선택할 수 있습니다.