템플릿과 슬롯 (<template>, <slot>)
<template> 태그는 화면에는 보이지 않지만, 나중에 자바스크립트를 사용해 찍어내듯 반복해서 사용할 HTML 구조를 담아두는 보관함입니다. 이는 브라우저 메모리에 파싱된 상태로 대기하므로 성능상 매우 유리합니다.
<slot>은 이 템플릿 안에서 '내용이 들어갈 빈칸(구멍)' 역할을 합니다. 붕어빵을 만들 때 붕어빵 틀(Template)은 동일하지만, 안에 팥을 넣을지 슈크림을 넣을지(Slot) 결정할 수 있는 것과 같습니다. 이는 React나 Vue의 컴포넌트 재사용 원리의 근간이 됩니다.
<!-- 화면에 렌더링되지 않는 보관함 (템플릿) -->
<template id="user-card-template">
<div style="border: 2px solid #3b82f6; padding: 15px; border-radius: 8px; background: #1e293b; color: white; margin-bottom: 10px;">
<!-- 외부에서 주입될 내용이 들어갈 빈칸(슬롯) -->
<h3 style="margin:0 0 10px 0;"><slot name="username">이름 없음</slot></h3>
<p style="margin:0; color: #94a3b8;"><slot name="job">직업 미상</slot></p>
</div>
</template>
<!-- 복제된 카드들이 들어갈 컨테이너 -->
<div id="container"></div>
<script>
// 1. 템플릿과 컨테이너를 가져옵니다.
const template = document.getElementById('user-card-template');
const container = document.getElementById('container');
// 데이터 배열
const users = [
{ name: '김민수', job: '프론트엔드 개발자' },
{ name: '이영희', job: 'UI/UX 디자이너' }
];
// 2. 데이터를 순회하며 템플릿을 복제하여 화면에 붙입니다.
users.forEach(user => {
// 템플릿 내용 전체 복제 (true는 하위 노드까지 깊은 복사)
const clone = template.content.cloneNode(true);
// 복제된 내용 안의 빈칸(slot)을 실제 데이터로 교체
clone.querySelector('slot[name="username"]').textContent = user.name;
clone.querySelector('slot[name="job"]').textContent = user.job;
container.appendChild(clone);
});
</script>