Web Components Slot 사용하기

내가 만든 webcomponent 사이에, 사용자 html tag가 customizing 되어 적용되게 하는 방법을 알아보자.

2021.08.15 - [Web] - Web Component publish 공개 하기

 

Web Component publish 공개 하기

2021.08.14 - [Web] - Web component (Custom Elements, Shadow DOM, Template) 2021.08.14 - [Web] - Web Components Callback Methods & lifecycle 앞서서 Web Component를 만드는 방법에 대해서 알아 보았다...

enumclass.tistory.com

 

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 하기

 

Web Component Event Dispatching 하기

앞서 만든 Web Component로 부터 이벤트에 따른 변화를 알아야 한다면 어떻게 해야 할까? 가련 버튼을 클릭한 이벤트의 횟수를 외부에서 알아야 한다면? 두가지 방법이 있다. get 을 이용해서 public val

enumclass.tistory.com

 

Slot 사용이 안될 경우

shadowDom을 사용하는 경우에는 Slot이 작동하지만, shadowDom을 사용하지 않는다면 Slot은 작동되지 않는다.

만약에 Rendering전에 대상 컴포넌트 사이의 Contents를 살려야 한다면,

const preDom = this.innerHtml;

this.render();

이후에 

필요한 곳에 append 처리해줘야 한다.

this.querySelector('#pre').innerHtml = preDom;

이런식이다.

728x90
반응형