나의 개발 일지

웹컴포넌트 만들어보기 테스트2 class와 template 활용

designer DK 2024. 8. 11. 15:12
728x90

어제 자바스크립트로 웹컴포넌트 만들어보기 테스트를 진행하고 블로그 포스팅도 올렸었는데

유튜브 채널 드림코딩의 이 영상을 보고나니

자바스크립트 6. 클래스와 오브젝트의 차이점(class vs object)
https://www.youtube.com/watch?v=_DLhUBWsRtw

머릿속에 아주 어렴풋하게만 떠오르던 class의 개념이 좀 더 명확하게 정립되었고 그게 정립된 후에 어제 테스트해보았던 이 코드를 보니까

class CustomInput extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({ mode: 'open' });
       
        const template = document.getElementById('input-template')
        const content = template.content.cloneNode(true);
        this.shadowRoot.appendChild(content);
    }
}

customElements.define('custom-input', CustomInput)

 

 


만약에 이런식으로 

class CustomTitle extends HTMLElement {
    constructor() {
        super();
    }
    connectedCallback() {
        this.innerHTML = `<h1>Welcome, Web Component!</h1>`;
    }
}

customElements.define('custom-title', CustomTitle)

 

한 js에 꾸러미로 html들을 모두 포함할거라면 '타이틀'이라는 용도에 맞게 사용하도록 세팅된 컴포넌트라고 해도 수긍이 되는데

 


이 코드 같은경우 html부분이 애초에 탬플릿화 되어있고 만약 이부분을 변수화시켜서 속성으로 뺄 수 있다면

class CustomInput extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({ mode: 'open' });
       
        const template = document.getElementById(변수화?!)
        const content = template.content.cloneNode(true);
        this.shadowRoot.appendChild(content);
    }
}

customElements.define('custom-input', CustomInput)


이걸 용도별 컴포넌트로 규정하는 것보다는 어떠한 template들이 들어오더라도 모두 품어줄 수 있는 class로 활용할 수 있겠다고 생각되었다. 그리고 그렇게 되면 이 컴포넌트는 더이상 커스텀인풋 컴포넌트가 아닌 모든 탬플릿을 컴포넌트화로 풀어줄 수 있는 기막힌 class가 되지않을까? 라는 생각으로 도전!

그에 따라 이 파일을 개별적인 컴포넌트로 두지 않고 custom-template.js라는 파일로 만들고
여기에 html에서 template으로부터 가져오는 아이디 값을 어떤 아이디든 들어올 수 있게 변수화 시킨 폼으로 변경시킨 후
그걸 속성으로 빼서 html에서 제어할 수 있도록 세팅해보았다.

class CustomTemplate extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({ mode: 'open' });

        this.templateID = this.getAttribute("templateID");
        const template = document.getElementById(this.templateID)
        const content = template.content.cloneNode(true);
        this.shadowRoot.appendChild(content);
    }
}

customElements.define('custom-template', CustomTemplate)



그 결과 이런식으로 코드를 수정해보았는데 개인적으로는 이게 더 멋진 방법이라고 생각되어서 이렇게 방식을 바꾸기로 결정했다.

<body>
    커스텀탬플릿을 만들고 응용해보기
    <div class="insert"></div>
    <custom-template templateID = "input-component">
        <div class="bbb" slot="label-slot">라벨1</div>
        <img class="ccc" slot="img-slot" src="data/favicon.png" alt="">
    </custom-template>
    <custom-template templateID = "input-component">
        <div class="bbb" slot="label-slot">라벨2</div>
    </custom-template>
    <button id="btn">버튼</button>
   

<!-- 탬플릿 -->
    <template id="input-component">
        <style>
            .aaa {
                border: 2px solid red;
            }
            ::slotted(.bbb) {
                color:blue;
            }
            ::slotted(.ccc) {
                width: 24px;
            }
            .input-container {
                display: flex;
                gap: 20px;
            }
        </style>
        <slot name="label-slot"></slot>
        <div class="input-container">
            <slot name="img-slot"></slot>
            <input class="aaa" type="text">
        </div>
    </template>
   
    <script src="custom-template.js"></script>
    <script src="script.js"></script>
</body>



사실 이렇게 바꾸면 이게 원래 도전했던 웹컴포넌트라기보단 탬플릿을 넣어줄 수 있는 class라는 틀을 만든 케이스가 되는 것인데...나는 현재로써는 큰 상관은 없다고 판단되었다.

내가 컴포넌트를 활용하려던 목적은 이전 포스팅에서 이야기한대로 1 재사용성, 2 속성 제어. 이 두가지였고 오늘 발견한 이 방식으로도 이 두가지를 모두 충족할 수 있기 때문이다.

 

여담이지만 class라는 개념은 조금씩 알면 알아갈수록 재미있고 신기한 면이 많게 느껴졌다.
뭔가 세상의 모든 구조를 담을 수 있는 느낌이랄까...