프론트엔드/Vue

template 과 slot

bread-gee 2022. 9. 26. 09:59

template과 slot을 어떻게 쓸 수 있는지 너무 헷갈려서 검색해 보았다.

막연하게 사용했었는데, 위 두 태그가 HTML 태그 기반이라는 것을 알았다.

사용 방법은 Vue에서 사용하던 것과 같다.

다만, 좀 더 구체적으로 두 태그를 알게 되었다.

 

HTML <template> 태그 : 콘텐츠 template 요소

<template> 엘리먼트는 페이지를 불러온 순간 즉시 그려지지는 않지만, 

이후 JavaScript를 사용해 인스턴스를 생성할 수 있는 HTML 코드를 담을 방법을 제공한다.

(페이지가 load 될 때, HTML 코드 조각을 담아 놓는 안 보이는 요소이다.)

 

<template> 엘리먼트는 콘텐츠 조각을 나중에 사용하기 위해 담아놓는 컨테이너

페이지를 불러오는 동안 구문 분석기가 <template> 요소의 콘텐츠도 읽기는 하지만, 이는 유효성을 검증하기 위함이며 렌더링 하기 위함은 아니다. => 렌더링 되지는 않는다.

 

<template>에 ID 를 지정하고, JS는 템플릿 안의 콘텐츠를 가져와 웹 페이지에 추가하는 데 사용된다.

 

페이지가 로드될 때 즉시 렌더링되지 않는 HTML을 담고 있는 HTML 요소 매커니즘이다.

그후 런타임 중에 JS 의해 인스턴스화된다.

 

예시 코드

<body>
	<button onclick="showContent()">숨겨진 콘텐츠를 보여줘!</button>

	<template>
		<h2>Test Text</h2>
	</template>
</body>

<script>
function showContent() {
	const temp = document.getElementsByTagName("template")[0];
	const clon = temp.content.cloneNode(true);
	document.body.appendChild(clon);
}
</script>

 

HTML <slot> 태그 : 웹 컴포넌트 Slot 요소

웹 컴포넌트 사용자가 자신만의 마크업으로 채워 별도의 DOM 트리를 생성하고, 컴포넌트와 함께 표현할 수 있는 웹 컴포넌트 내부의 플레이스 홀더이다.

 

보통 shadow tree에서 사용된다.

할당된 노드가 있을 경우 그걸 보여주고, 그렇지 않을 경우엔 콘텐츠를 보여준다.

 

예시 코드

<body>
	<template>
		<h1><slot name="heading"></slot></h1>
	</template>
	<span slot="heading">Test Text</span>
</body>

 


 

VUE에서의 template

1. DOM의 template 옵션

컴포넌트 인스턴스의 마크업으로 사용할 문자열 템플릿

템플릿은 마운트 된 엘리먼트를 한다.

템플릿에 콘텐츠 배포 슬롯(content distribution slots)이 없는 경우, 마운트 된 엘리먼트의 기존 마크업은 무시된다.

* Vue 옵션에 렌더 함수가 있으면, 템플릿은 무시된다.

 

2. <template>에 v-if를 이용하여 조건부 그룹으로 사용하기

<template> 엘리먼트는 눈에 보이지 않게 내부 엘리먼트를 감싸는 역할(invisible wrapper)을 하며, 최종 렌더링 결과에 포함되지 않는다.

 

요소들 여러 개가 있을 , 해당 요소들을 번에 전환시킬 사용한다.

// <template>을 사용하지 않을 경우
<div class="description" v-if="condition">
	<span>내용</span>
</div>
<div class="detail" v-if="condition">
	<span>내용</span>
</div>

// <template>을 사용 할 경우
<template v-if="condition">
	<div class="description">
		<span>내용</span>
	</div>
	<div class="detail">
		<span>내용</span>
	</div>
</template>

 

VUE에서의 slot

템플릿의 조각을 자식 요소에 전달하고, 자식 요소가 해당 부분을 자체적으로 렌더링하도록 할 수 있다.

=> 상위 콘텐츠의 슬롯 콘텐츠가 렌더링 되어야 하는 위치를 나타낸다.

 

1. default slot

slot 렌더링 방법

<button /><slot />으로 구성된 <FancyButton> 컴포넌트에 내용을 추가하면

<FancyButton> 컴포넌트의 <slot> 영역에 내용이 추가되어 렌더링 된다.

 

2. 이름이 있는 slot

<template>의 v-slot 속성과 <slot>의 name 속성이 매칭되어 렌더링 된다.

 

// parent template
<template>
	<ChildComponent>
		<template v-slot=“header”>헤더</tempate>
		<template v-slot=“body”>바디</tempate>
	</ChildComponent>
</template>

// ChildComponent template
<template>
	<div>
		<slot name="header">v-slot헤더가 없으면, 지금 이 텍스트가  출력된다.</slot>
		<slot name="body">v-slot바디가 없으면, 지금 이 텍스트가  출력된다.</slot>
	</div>
</template>

 

 


 

참고

MDN

<template> 태그

https://developer.mozilla.org/ko/docs/Web/HTML/Element/template

https://html.spec.whatwg.org/multipage/scripting.html#the-template-element

 

<slot> 태그

https://developer.mozilla.org/ko/docs/Web/HTML/Element/slot

https://html.spec.whatwg.org/multipage/scripting.html#the-slot-element

 

<template> 과 <slot> 함께 사용하기

https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots