어제 자바스크립트로 웹컴포넌트 만들어보기 테스트를 진행하고 블로그 포스팅도 올렸었는데
유튜브 채널 드림코딩의 이 영상을 보고나니
자바스크립트 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라는 개념은 조금씩 알면 알아갈수록 재미있고 신기한 면이 많게 느껴졌다.
뭔가 세상의 모든 구조를 담을 수 있는 느낌이랄까...