Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 개발자 특강
- Frontend Roadmap
- react customHook 예시
- 프로그래머스 데브코스
- 모던 자바스크립트 Deep Dive TIL
- 모던 자바스크립트 TIL
- useRef 지역 변수
- useEffect return
- 프로그래머스 데브코스 프론트엔드
- 모던 javascript Deep Dive
- 모던 자바스크립트 딥다이브
- 투포인터알고리즘 js
- 인프런 자바스크립트 알고리즘 문제풀이
- Vue3
- 백준 node.js
- 머쓱이
- 백준 js
- TypeScript 문법 소개
- 리팩토링 회고
- 프로그래머스 데브코스 프론트엔드 TIL
- react 프로젝트 리팩토링
- K_Digital Training
- Vue3 Router
- 모던 자바스크립트 Deep Dive
- 프로그래머스 K_Digital Training 프론트엔드
- 우테캠 회고록
- KDT 프로그래머스
- frontend roadmap study
- KDT 프로그래머스 데브코스 프론트엔드
- 프로그래머스 K_Digital Training
Archives
- Today
- Total
프론트엔드 개발자의 기록 공간
[FE_Roadmap] Web Components 본문
Web Components
- 웹 컴포넌트는 그 기능을 나머지 코드로부터 캡슐화하여 재사용 가능한 커스텀 엘리먼트를 생성하고 웹 앱에서 활용할 수 있도록 해주는 다양한 기술들의 모음입니다.
- 웹 표준 기술로 모든 브라우저에서 동작하고 플랫폼 간 호환성을 높여줍니다. (미지원 브라우저 제외 및 구버전 브라우저에서는 polyfill을 사용하여 지원 가능)
- 다양한 프레임워크나 라이브러리에서 Web Components를 사용할 수 있기 때문에, 기술 스택에 구애받지 않고 사용할 수 있습니다.
특징
- Custom elements
- html tag 자체를 커스텀하게 만들고 browser 사용할 수 있도록 만들어 줍니다.
customElements.define
메소드를 이용
- Shadow DOM
- 다른 DOM과의 분리를 통해 DOM을 캡슐화합니다.
- shadow dom 외부의 js는 접근이 안된다.
- shadow boundary의 style은 외부로 영향을 미치지 않는다.
- 브라우저 미 지원시 polyfill 사용
shadowRoot.querySelector()
메소드를 이용
- HTML templates
<template>
과<slot>
엘리먼트는 렌더링된 페이지에 나타나지 않는 마크업 템플릿을 작성할 수 있게 해줍니다. 그 후, 커스텀 엘리먼트의 구조를 기반으로 여러번 재사용할 수 있습니다.content.cloneNode(true)
메소드를 이용
- Declarative Shadow DOM
- 내용이 다소 많아 잘 정리된 블로그로 대체합니다.
- https://ui.toast.com/posts/ko_20201007
lifecycle
class MyCustomElement extends HTMLElement {
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"]
}
}
connectedCallback
- 요소가 DOM에 추가되면 메서드가 트리거됩니다.
- 리소스를 가져오고, 설정 코드를 실행하거나 템플릿을 렌더링할 수 있습니다.
react useEffect와 비슷한듯? 대신 렌더링 시점과 DOM 추가 시점이 다른 듯..
class MyCustomElement extends HTMLElement {
connectedCallback() {
console.log("connected")
}
}
customElements.define("my-custom-element", MyCustomElement)
const myCustomElement = new MyCustomElement()
document.body.appendChild(myCustomElement)
document.body.appendChild(myCustomElement)
// result:
// 'connected'
// 'connected'
disconnectedCallback
- 요소가 DOM에서 제거될 때 트리거됩니다.
- DOM 이벤트 구독 취소
- 간격 타이머 중지
- 글로벌 또는 애플리케이션 서비스에 등록된 모든 콜백 등록 취소
react useEffect의 return과 비슷한듯?
class MyCustomElement extends HTMLElement {
disconnectedCallback() {
console.log("disconnected from the DOM")
}
}
customElements.define("my-custom-element", MyCustomElement)
document.querySelector("my-custom-element").remove() // 'disconnected from the DOM'
attributeChangedCallback(attrName, oldVal, newVal)
- name: 속성의 이름을 나타냅니다. oldValue: 속성의 이전 값을 나타냅니다. newValue: 속성의 새 값을 나타냅니다.
- attributeChangedCallback속성이 추가, 제거, 업데이트 또는 교체되거나 구성 요소 인스턴스가 업그레이드될 때 트리거됩니다.
- 추적할 속성은 static get observedAttributes속성 이름 배열을 반환하는 메서드에 지정됩니다.
react 의존성 배열 deps와 비슷한듯?
<my-custom-element
prop1="foo"
prop2="bar"
prop3="baz">
</my-custom-element>
...
class MyCustomElement extends HTMLElement {
static get observedAttributes() {
return ["prop1", "prop2", "prop3"]
}
attributeChangedCallback(name, oldValue, newValue) {
console.log(
`${name}'s value has been changed from ${oldValue} to ${newValue}`,
)
}
}
adoptedCallback()
<iframe/>
iframe과 같은 외부 요소에서 사용됩니다.- 이러한 일이 발생하면 adoptedCallback수명 주기 후크가 트리거됩니다. 이를 사용하여 소유자 문서, 기본 문서 또는 기타 요소와 상호 작용할 수 있습니다.
실제 사용 예시
- 카운터 구성 요소에는 다음이 포함됩니다.
- 현재 값을 증가시키는 증가 버튼
- 현재 값을 감소시키는 감소 버튼
- 현재 값을 표시하는 레이블
- "value" 속성을 통해 기본값을 설정할 수 있어야 합니다.
const template = document.createElement("template")
template.innerHTML = `
<button id="increaseBtn">+</button>
<span id="label"></span>
<button id="decreaseBtn">-</button>
`
export class CounterComponent extends HTMLElement {
// define the observedAttributes array
static get observedAttributes() {
return ["value"]
}
// define getters and setters for attributes
get value() {
return this.getAttribute("value")
}
set value(val) {
if (val) {
this.setAttribute("value", val)
} else {
this.removeAttribute("value")
}
}
// DOM 요소 참조 변수
$increaseButton
$decreaseButton
$label
constructor() {
super()
// Shadow DOM 사용
this.attachShadow({ mode: "open" })
this.shadowRoot.appendChild(template.content.cloneNode(true))
// DOM 요소에 대한 참조를 설정합니다.
this.$increaseButton = this.shadowRoot.querySelector("#increaseBtn")
this.$decreaseButton = this.shadowRoot.querySelector("#decreaseBtn")
this.$label = this.shadowRoot.querySelector("#label")
}
connectedCallback() {
// 양쪽 버튼에 이벤트 리스너 추가
// 리스너의 콜백에 "this"를 바인딩하여 컴포넌트의 스코프를 연결합니다.
this.$increaseButton.addEventListener("click", this._increase.bind(this))
this.$decreaseButton.addEventListener("click", this._decrease.bind(this))
}
disconnectedCallback() {
// 양쪽 버튼에서 이벤트 리스너 제거
this.$increaseButton.removeEventListener("click", this._increase.bind(this))
this.$decreaseButton.removeEventListener("click", this._decrease.bind(this))
}
attributeChangedCallback(name, oldValue, newValue) {
this.$label.innerHTML = newValue
}
adoptedCallback() {
console.log("I am adopted!")
}
_increase() {
const value = +this.value
this.value = String(value)
}
_decrease() {
const value = +this.value
this.value = String(value)
}
}
https://ultimatecourses.com/blog/lifecycle-hooks-in-web-components
브라우저 호환성
- 웹 컴포넌트는 기본적으로 Firefox (버전 63), Chrome, 및 Opera 에서 지원됩니다.
- Safari 는 많은 웹 컴포넌트 기능을 지원하지만 위 브라우저들만큼은 아닙니다.
- Edge 는 구현 작업중입니다.
728x90
'개발지식' 카테고리의 다른 글
requestAnimationFrame 사용법 (1) | 2024.05.26 |
---|---|
[FE_Roadmap] writing css & testing your apps (0) | 2024.03.02 |
[FE_Roadmap] Pick a Framework (1) | 2024.02.18 |
[FE_Roadmap] Module Bundlers (0) | 2024.02.13 |
[FE_Roadmap] CSS Architecture&CSS Preprocessors (1) | 2023.12.17 |
Comments