JS Web Component API(2024-11-26 수업)

짝은별·2024년 11월 26일

JS

목록 보기
19/23

웹 컴포넌트

웹 컴포넌트란?
본인이 원하는 대로 태그의 이름과 스타일을 미리 설정하고
이를 바탕으로 편하게 복제를 하며 재사용이 가능하다
즉, 컴포넌트의 역할을 수행하는 것이다

그렇다면 사용하는 이유는 무엇일까?

우선 재사용가능하다는 점과 캡슐화를 통해 원하는 속성을 통제할 수 있다는 장점이 있다

class MyElement extends HTMLElement {
  constructor() {
    super();
    // 엘리먼트가 생성됨
  }

  connectedCallback() {
    // 엘리먼트가 문서에 추가될 때 브라우저가 이 메서드를 호출합니다.
    // (엘리먼트가 반복적으로 추가/제거되면 여러 번 호출될 수 있음)
  }

  disconnectedCallback() {
    // 엘리먼트가 문서에서 제거될 때 브라우저가 이 메서드를 호출합니다.
    // (엘리먼트가 반복적으로 추가/제거되면 여러 번 호출될 수 있음)
  }

  static get observedAttributes() {
    return [/* 변경 사항을 모니터링할 속성 이름의 배열 */];
  }

  attributeChangedCallback(name, oldValue, newValue) {
    // 위에 나열된 속성 중 하나가 수정될 때 호출됩니다.
  }

  adoptedCallback() {
    // 엘리먼트가 새 문서로 이동될 때 호출됩니다.
    // (document.adoptNode에서 사용되며 매우 드물게 사용됨)
  }

  // 다른 엘리먼트 메서드와 속성이 있을 수 있습니다.
}

사용하기 위해선 class 문법을 사용해 생성한다
extends HTMLElement를 기재하여 HTMLElement의 속성을 부여받는다

기본 설정 값으로는 다음 4가지가 있다

  • connectedCallback()
  • disconnectedCallback()
  • attributeChangedCallback(name, oldValue, newValue)
  • adoptedCallback()

하나하나 살펴보자

connectedCallback()

이는 선언한 Element가 HTML에 사용될때 실행하는 함수이다

disconnectedCallback()

선언한 Element가 HTML에 사용되었다가 다시 사라질때 실행되는 함수이다(종료)

attributeChangedCallback()

만약 선언한 Element에 변화가 생긴다면 그 값을 가지고 원하는 동작을 실행시킬 수 있는 함수이다
이를 잘 활용한다면 시계를 나타내는 것도 가능하다
(초가 계속해서 바뀌므로 이를 인식해서 화면에 렌더링한다)

adoptedCallback()

선언한 Element가 새로운 document에 사용되었다면 호출되는 함수이다

물론 이를 제외하고 원하는 함수class의 내부에 입력해도 정상적으로 사용이 가능하다
이 과정에서 이벤트를 할당하는 것도 역시 가능하다

이를 통해 알 수 있는 점은 web componenet apilife cycle이 존재한다는 것이다
connectedCallback으로 시작을 알리고 disconnectedCallback으로 마지막을 알린다

그렇다면 custom Element를 만드는 과정을 살펴보자

customElements.define("my-element", MyElement);

customElements.define으로 첫 번째 인수에는 생성할 태그의 이름을, 두 번째 인수에는 어떤 class를 이용해서 만들 것인지를 정할 수 있다

참고로 첫 번째 인수의 이름에는 반드시 하이픈(-)이 포함되어야 한다

shadow DOM

shadow DOM강력한 캡슐 기술이다
이는 일반적인 JS호출이나 셀렉터접근할 수 없다

DOM에는 shadow DOMlight DOM이 있다
우선 light DOM일반적인 HTML에 사용되는 태그들로 구성된다
여기에는 접근하기 용이하고 조작하기도 수월하다

그에 반해 shadow DOM은 표면에 나타나지 않고 숨어있는 녀석이다

만약 light DOMshadow DOM동시에 선언되었다면 우선 순위shadow DOM이 높아 light DOM은 가려진다(shadowing)

그렇다면 shadow DOM에는 어떻게 접근할까?
방법은 아래와 같다

class MyElement extends HTMLElement {
  constructor() {
    super();
  }
  
  connectedCallback() {
    const shadow = this.attachShadow({mode:'open'});
    console.log(shadow);
  }
  
  
  
}

customElements.define('my-div' , MyElement);
const myDiv = document.createElement('my-div');
document.body.appent(myDiv);

우선 코드의 흐름을 먼저 살펴보면 class는 태그를 어떤 방식으로 생성할지를 정한다
그 후 customElements.define을 사용해 'my-div'라는 태그를 MyElement를 이용해 생성한다
이를 body에 붙여주는 것이다

마지막 과정에서 bodyattach 즉, 탄생했으므로 connectedCallback()이 실행되고 shadow를 정상적으로 출력하는 모습이다

원래였으면 접근을 못하지만 mode:'open'으로 인해 접근이 가능해진 모습이다

하지만 이러한 방식을 사용해도 img 태그와 같은 곳은 shado DOM에 접근이 불가능하다

이러한 설정이 완료되었다면 document.querySelector와 같이 shadow에도 같은 방식으로 사용이 가능하다

  connectedCallback() {
    this.attachShadow({mode:'open'});
    console.log(this.shadowRoot.querySelector('div'));
  }

와 같은 방식으로 사용이 가능하다
지금은 tag를 생성할때 내부에 생성한 태그가 없으므로 값은 반환이 되진 않는다

주의점

shadow DOM은 강력한 캡슐 기능이라고 소개했다
그렇기에 외부에서 접근하는 것은 불가능하다
따라서 CSS속성을 문서로 부여하는 것은 불가능하다
만약 CSS속성을 주고 싶다면 인라인 방식 혹은, style 태그를 내부에 생성하여 CSS를 적용시킬 수 있다

이는 뒤에 나올 shadow DOM styling에서 더 자세히 보자

template태그

HTML문서template 태그를 사용하여 감싸면
휘발되어 렌더링이 되지 않는다

이는 component처럼 사용이 가능한 태그이다
미리 생성해놓고 원하는 곳에 append를 통해 렌더링이 가능하도록 한다

슬롯

앞서 말했듯 light DOMshadow DOM동시에 사용하게 되면 shadow DOM의 우선순위가 높아 light DOM이 무시된다
이를 해결하고자 슬롯을 사용하는 것이다

우선 사용법은 다음과 같다

    this.shadowRoot.innerHTML = `
      <div>Name:
        <slot name="username"></slot>
      </div>
      <div>Birthday:
        <slot name="birthday"></slot>
      </div>
    `;
<user-card>
  <span slot="username">John Smith</span>
  <span slot="birthday">01.01.2001</span>
</user-card>

만약 이 경우 원래대로였으면 user-card내부에 있는 span태그들은 shadow DOM의 선언으로 인해 무시되었어야 한다
하지만 slot을 사용하여 HTML에 선언된 span태그slot 속성의 값을 확인하여
shadow DOM에서 선언된 slot태그name속성의 값일치한다면 렌더링을 한다

이때 span태그light DOM에 포함되고 문서에서 선언한 CSS도 적용이 가능하다

그리고 동일한 이름을 가진 슬롯의 경우 순서대로 추가된다
첫 번째 슬롯이름이 지정되지 않았다면 모든 값을 포함하게 된다

또한 slot함수의 매개변수default value를 설정하듯이 slot fallback을 설정할 수 있다
이는 단순히 태그값을 기재하는 것으로 작성할 수 있다

shadow DOM styling

:host를 사용하게 되면 본인을 생성한, 즉 렌더링한 대상지정하여 style을 부여할 수 있게된다
이것이 필요한 이유는 shadow DOM에는 정상적인 방법으로 접근이 어렵고, 생성되기 전에 미리 접근하는 방법은 없다
따라서 이러한 방법을 이용하여 CSS를 적용하는 것이다

하지만 hostlight DOM에 있으므로 문서 CSS 규칙의 영향을 받는다

또한 hostselector(::after 등)도 역시 설정이 가능하다

정말 편리한 방식은 내부에 style 태그에 미리 생성해둔 CSS문서@import('문서 경로')를 사용하여 설정도 가능하다
주의해야할 점 문서의 경로는 항상 내보내는 문서를 기준으로 작성해야한다

profile
FE(철 아님) 개발자 꿈꾸다

0개의 댓글