Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
Tags
- live share
- typescript
- browserslist
- 우아한테크코스
- custom element
- docker-compose
- RTL8852BE
- webpack
- react
- 데모데이
- javascript
- 유한 상태 머신
- fastify
- github Actions
- react-dom
- Docker
- 무선랜카드 교체
- Shadow DOM
- AX210
- swiper
- Prometheus
- GitHub Pages
- CSS
- 우아한테크코스 레벨3
- Grafana
- HTML
- scroll-snap
- 터치 스와이프
- 우테코
- web component
Archives
- Today
- Total
IT일상
[Web Component] Custom Element에서 slot 사용하기 본문
리뉴얼 된 블로그로 보기: https://solo5star.dev/posts/28/
<body>
<p>안녕하세요. 오늘도 좋은 날씨네요!</p>
<my-modal>
<!-- 여기에 모달의 내용을 넣고 싶다 -->
</my-modal>
</body>
my-modal이라는 Custom Element를 만들었습니다. 모달의 모양만 가지고 있는 엘리먼트인데, 그럼 모달안의 내용은 어떻게 전달할까요?
Light DOM
<body>
<p>안녕하세요. 오늘도 좋은 날씨네요!</p>
<my-modal>
<h1>오늘 날씨는 15도입니다.</h1>
<p>기온이 많이 올라갔지만 따뜻하게 입는 것 잊지 마세요!</p>
</my-modal>
</body>
customElements.define('my-modal', class MyModal extends HTMLElement {
constructor() {
super();
this.childrenHTML = this.innerHTML;
this.innerHTML = `
<style>
dialog::backdrop {
background: rgba(0, 0, 0, 0.3);
}
</style>
<dialog>
<form method="dialog">
${this.childrenHTML}
<button>확인</button>
</form>
</dialog>
`;
}
connectedCallback() {
this.querySelector('dialog').showModal();
}
});
Shadow DOM을 사용하지 않을 시, <my-modal> 내의 HTML은 innerHTML로 접근할 수 있습니다.
임시로 this.childrenHTML에 저장한 후 위와 같이 템플릿에 삽입할 수 있습니다.
(childrenHTML은 임의로 정한 이름이기 때문에, 다른 걸로 바꾸어 사용해도 무관합니다)
Shadow DOM
만일 Shadow DOM을 사용한다면 위의 방법대로 할 수 있을까요?
Shadow DOM의 경우, slot element를 사용하면 됩니다.
<body>
<p>안녕하세요. 오늘도 좋은 날씨네요!</p>
<my-modal>
<h1>오늘 날씨는 15도입니다.</h1>
<p>기온이 많이 올라갔지만 따뜻하게 입는 것 잊지 마세요!</p>
</my-modal>
</body>
customElements.define('my-modal', class MyModal extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
dialog::backdrop {
background: rgba(0, 0, 0, 0.3);
}
</style>
<dialog>
<form method="dialog">
<slot></slot> <!-- host의 내용을 여기에 표시 -->
<button>확인</button>
</form>
</dialog>
`;
}
connectedCallback() {
this.shadowRoot.querySelector('dialog').showModal();
}
});
<my-modal> 내의 html 내용은 <slot></slot> 에 표시됩니다.
slot에 이름 지정
slot에는 이름을 지정할 수도 있습니다.
<my-modal>
<h1 slot="title">오늘 날씨는 15도입니다.</h1>
<p slot="content">기온이 많이 올라갔지만 따뜻하게 입는 것 잊지 마세요!</p>
</my-modal>
customElements.define('my-modal', class MyModal extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
dialog::backdrop {
background: rgba(0, 0, 0, 0.3);
}
</style>
<dialog>
<form method="dialog">
<slot name="title"></slot>
<hr >
<slot name="content"></slot>
<button>확인</button>
</form>
</dialog>
`;
}
connectedCallback() {
this.shadowRoot.querySelector('dialog').showModal();
}
});
이름을 지정하면, slot을 여러 개 만들어 어떠한 위치에 삽입을 할 것인지도 결정할 수 있습니다.
::slotted()
::slotted() pseudo selector를 사용하면, slot 내의 엘리먼트에 대해 스타일을 지정할 수 있습니다.
<my-modal important>
<h1 slot="title">오늘 날씨는 15도입니다.</h1>
<p slot="content">기온이 많이 올라갔지만 따뜻하게 입는 것 잊지 마세요!</p>
</my-modal>
customElements.define('my-modal', class MyModal extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
dialog::backdrop {
background: rgba(0, 0, 0, 0.3);
}
:host([important]) ::slotted(h1) {
text-decoration: underline;
color: blue;
}
</style>
<dialog>
<form method="dialog">
<slot name="title"></slot>
<hr >
<slot name="content"></slot>
<button>확인</button>
</form>
</dialog>
`;
}
connectedCallback() {
this.shadowRoot.querySelector('dialog').showModal();
}
});
맺음말
slot 기능을 사용하면 외부에서 <my-button>, <my-alert> 등의 엘리먼트들을 조합하여 사용할 수 있습니다. 따라서 컴포넌트를 재사용하는 데에 큰 도움이 되니 잘 사용하면 좋을 것 같습니다.
'프론트엔드' 카테고리의 다른 글
타입스크립트 템플릿 리터럴 타입 (0) | 2023.03.27 |
---|---|
[Web Component] 커스텀 폼 컨트롤, form associated 컴포넌트 만들기 (2) | 2023.03.07 |
[Web Component] 컴포넌트 내부 요소를 격리하기. HTML Custom Elements + Shadow DOM (0) | 2023.02.27 |
GitHub Actions: Webpack 빌드 + GitHub Pages 배포 자동화하기 (15) | 2023.02.24 |
[Web Component] VanillaJS에서 React처럼 개발하기. HTML Custom Elements 소개 (2) | 2023.02.23 |
Comments