[웹 컴포넌트] Custom Elements

Chad Lee·2023년 2월 14일
1

web-components

목록 보기
1/5

기본 설명

Custom Elements는 사용자 HTML Element를 만들게 해준다. 그리고 이는 DOM의 모든 기능을 다 사용 할 수 있다.

기본적으로 두 가지 타입으로 생성한다.

  • 표준 HTML 요소를 상속하지 않은 Element. 요소는 상속하지 않지만 HTMLElement는 상속 한다.
  • 표준 HTML 요소를 상속한 Element.

이렇게 생성한 Element는 Lifecycle callback을 class 안에 정의하여 특정 시점에 동작 하도록 한다.

기본 사용법

독립적인 사용자 정의 요소

class MyElement extends HTMLElement {
	constructor() {
    // 항상 super를 호출 해야 한다.
		super();

    this.innerHTML = `<h1>This is My Element</h1>`
	}

}

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

customElements.define에서 정의할 때 아래 사항을 꼭 유념 해야 한다.

Name for the new custom element. Note that custom element names must contain a hyphen. by-MDN

constructor 메서드 안에 this는 customElements를 가리킨다. <my-element> 를 사용해 보면 <h1> Element가 생성 되고 This is My Element가 표현 된다.

Built-in 사용자 정의 요소

먼저 상속할 Element를 extends 하여 class를 정의 한다.

class MyButton extends HTMLInputElement {
	constructor() {
		super();

		this.style.border = '1px solid';
		this.addEventListender('click', (e) => e.preventDefault());
	}
}

정의한 사용자 요소를 등록합니다. 이때 상속한 Element를 인수로 넘겨 준다.

customElements.define("my-button", MyButton, {
  extends: "button",
});

마지막으로 <button> 사용 시 is attribute에 my-button을 사용자 요소로 사용함을 알려 준다.

<button is='my-button'>Click</button>

생명 주기 콜백

custom component가 생성되고 삭제 되기 까지 네 가지 상태에 따른 별도의 callback을 정의 할 수 있습니다. MDN에 따르면 아래와 같은 주기를 가진다.

connectedCallback: “사용자 정의 요소가 문서에 연결된 요소에 추가될 때마다 호출됩니다. 이것은 노드가 이동 될 때마다 발생할 것이며, 요소의 내용이 완전히 해석되기 전에 발생할 지도 모릅니다.”

disconnectedCallback: “사용자 정의 요소가 document DOM에서 연결 해제 되었을 때 마다 호출됩니다.”

adoptedCallback: ”사용자 정의 요소가 새로운 document로 이동 되었을 때마다 호출됩니다.”

attributeChangedCallback: “사용자 정의 요소의 특성들 중 하나가 추가되거나, 제거되거나, 변경될 때마다 호출됩니다. 어떤 특성이 변경에 대해 알릴지는 static get observedAttributes
메서드에서 명시됩니다.

위 생명 주기 콜백은 보면 React, Vue 등에서 사용했던 componentDidMount mounted와 비슷한 모양입니다. 사용법도 아래와 같이 비슷하다.

conntectedCallback() {
  console.log('연결 완료');
}
disconnectedCallback() {
  console.log('연결 해제 완료');
}
adoptedCallback() {
  console.log('Element가 다른 page로 이동 하였습니다.');
}
attributeChangedCallback(name, oldValue, newValue) {
	console.log('name 이 변경 되었습니다.');
}

static get observedAttributes() {
  // 변경을 관찰하고자 하는 attribute를 나열한다.
  // 아래 반환값들이 변경되면 `attributeChangedCallback` callback이 호출된다.
	return ['autofocus', 'disabled', 'form', 'value']
}

마치며

React, Vue와 같은 컴포넌트 기반 어플리케이션 개발에 유용하다고 생각 된다.

구현하는데 boilerplate가 포함되는 것을 보니 라이브러리가 있을 것으로 생각되어 찾아보니 역시 여러 라이브러리들이 있었다.

https://github.com/material-components/material-web

https://github.com/PolymerElements?page=3

Lit

다양한 directive 들과 api, cache관리 방법을 제공해 유용해 보였으나 애초에 vender 의존성을 피하고자 web components를 도입하려는 프로젝트에 과연 필요 할까 하는 생각이 든다.

0개의 댓글