내가 만든 webcomponent 사이에, 사용자 html tag가 customizing 되어 적용되게 하는 방법을 알아보자.
2021.08.15 - [Web] - Web Component publish 공개 하기
Slot이 필요한 이유는?
앞서 작성한 html의 Component 사용 형상은 아래와 같은 형태였다.
<company-header icon="./icon.png" page-name="My Page">
</company-header>
tag name이 있고 attributes가 있으면 해당 정보를 바탕으로 아래와 같이 javascript에서 컴포넌트가 작동하는 것이다.
export default class CompanyHeader extends HTMLElement{
constructor(){
super();
this.icon = '';
this.title = '';
this.shadowObj = this.attachShadow({mode:'open'});
}
render(){
const template = this.getTemplate();
this.shadowObj.innerHTML = template;
// this.innerHTML = template;
}
getTemplate(){
return `
<a href="/chapter3.html">
<img class="icon" src=${this.icon}></img>
</a>
<h1 class="heading">${this.title}</h1>
<div>
<a class="header-links">home</a>
<a class="header-links">About Us</a>
</div>
<style>
:host {
display: flex;
background: #44afdc;
align-items: center;
justify-content: center;
padding: 0 10px;
}
.icon {
width:50px;
height: 50px;
border-radius: 50%;
background: white;
}
.heading {
flex:1;
color : white;
padding-left: 20px;
}
.header-links {
text-decoration: none;
padding: 20px;
color: white;
}
</style>
`;
}
connectedCallback(){
this.render();
}
disconnectedCallback(){
}
adoptedCallback(){
}
static get observedAttributes(){
return ['icon','page-name'];
}
attributeChangedCallback(name, oldValue, newValue){
if(name === 'icon'){
this.icon = newValue;
}
if(name === 'page-name'){
this.title = newValue;
}
this.render();
}
};
customElements.define('company-header',CompanyHeader);
- 그런데 만약에 my page와 home 사이에 어떤 값을 넣고 싶다면 어떻게 해야할까?
Slot을 사용해 보자
이때 사용되는 것이 slot이다.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/slot
web component의 한가지 기술로써 component내의 html tag를 위치시키는 곳을 나타내는 역할을 보여준다.
그럼 이제 my page와 home 사이에 어떤 text를 넣어보자.
<a href="/chapter3.html">
<img class="icon" src=${this.icon}></img>
</a>
<h1 class="heading">${this.title}</h1>
<div>
<slot name="slot-test"></slot>
</div>
<div>
<a class="header-links">home</a>
<a class="header-links">About Us</a>
</div>
위의 getTemplate 메서드에 있는 html에 slot을 넣자.
그리고 html 파일에 아래와 같이 slot을 지정해 주자.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>Document</title>
</head>
<body>
<company-header icon="./icon.png" page-name="My Page">
<h1 slot="slot-test">
Slot Test Text
</h1>
</company-header>
<company-login></company-login>
<script type="module" src="CompanyHeader.js"></script>
<script type="module" src="CompanyLogin.js"></script>
</body>
</html>
이제 우리의 컴포넌트에 사용자가 원하는 html을 넣을 수 있게 되었다.
2021.08.14 - [Web] - Web Component Event Dispatching 하기
Slot 사용이 안될 경우
shadowDom을 사용하는 경우에는 Slot이 작동하지만, shadowDom을 사용하지 않는다면 Slot은 작동되지 않는다.
만약에 Rendering전에 대상 컴포넌트 사이의 Contents를 살려야 한다면,
const preDom = this.innerHtml;
this.render();
이후에
필요한 곳에 append 처리해줘야 한다.
this.querySelector('#pre').innerHtml = preDom;
이런식이다.
'Web' 카테고리의 다른 글
기존 web site를 components 로 다시 만들기 (No State management) (0) | 2021.08.16 |
---|---|
Web Component Event Dispatching 하기 (0) | 2021.08.15 |
Web Component publish 공개 하기 (0) | 2021.08.15 |
Web Components Callback Methods & lifecycle (0) | 2021.08.14 |
Web component (Custom Elements, Shadow DOM, Template) (0) | 2021.08.14 |