> 웹 프론트엔드 > CSS 튜토리얼 > 상호 운용 가능한 웹 구성 요소 구축

상호 운용 가능한 웹 구성 요소 구축

尊渡假赌尊渡假赌尊渡假赌
풀어 주다: 2025-03-13 10:05:10
원래의
464명이 탐색했습니다.

상호 운용 가능한 웹 구성 요소 구축

몇 년 이상 웹 개발자였던 사람들은 아마도 하나 이상의 JavaScript 프레임 워크를 사용하여 코드를 작성했을 것입니다. 반응, 벨트, vue, 각도, 단단함 등 모든 선택이 불가피합니다. 프레임 워크를 가로 질러 작업 할 때 가장 실망스러운 것 중 하나는 버튼, 탭, 드롭 다운 등 모든 저수준 UI 구성 요소를 다시 만들어내는 것입니다. 특히 실망스러운 것은 일반적으로 하나의 프레임 워크로 정의해야하지만 반응에 대해 다시 작성해야한다면 다시 작성해야한다는 것입니다. 또는 vue. 또는 단단합니다. 등.

이러한 저수준 UI 구성 요소를 프레임 워크 공유 방식으로 한 번 정의 한 다음 프레임 워크간에 재사용 할 수 있다면 더 나을 수 없습니까? 물론 그럴 것입니다! 그리고 우리는 할 수 있습니다. 웹 구성 요소가 방법입니다. 이 게시물은 방법을 보여줄 것입니다.

현재 웹 구성 요소에 대한 SSR 스토리는 약간 부족합니다. DSD (Declarative Shadow Dom)는 웹 ​​구성 요소가 서버 측 렌더링되는 방식이지만,이 글을 쓰는 시점에서 Next, Remix 또는 Sveltekit과 같은 좋아하는 애플리케이션 프레임 워크와 통합되지는 않습니다. 그것이 당신에게 요구되는 경우, DSD의 최신 상태를 확인하십시오. 그러나 그렇지 않으면 SSR이 사용하는 것이 아니라면 계속 읽으십시오.

먼저, 어떤 맥락

웹 구성 요소는 본질적으로 또는 기초에서 자신을 정의하는 HTML 요소입니다. 그들은 CSS 트릭 (CSS-Tricks) (Caleb Williams의 광범위한 시리즈와 John Rhea의 광범위한 시리즈 포함)에서 여기에서 다루었지만 우리는 그 과정을 간단히 살펴 보겠습니다. 기본적으로 JavaScript 클래스를 정의하고 HtmlElement에서 상속받은 다음 웹 구성 요소가 가지고있는 속성, 속성 및 스타일을 정의하고 물론 사용자에게 렌더링 할 마크 업을 정의합니다.

특정 구성 요소에 결합되지 않은 사용자 정의 HTML 요소를 정의 할 수있는 것은 흥미 롭습니다. 그러나이 자유는 또한 한계입니다. JavaScript 프레임 워크와 독립적으로 존재한다는 것은 이러한 JavaScript 프레임 워크와 상호 작용할 수 없다는 것을 의미합니다. 일부 데이터를 가져 오는 반응 구성 요소를 생각한 다음 데이터를 전달하는 다른 반응 구성 요소를 렌더링합니다. 웹 구성 요소가 React 구성 요소를 렌더링하는 방법을 모르기 때문에 웹 구성 요소로 작동하지 않습니다.

웹 구성 요소는 특히 잎 구성 요소 로 뛰어납니다. 잎 구성 요소 는 구성 요소 트리에서 마지막으로 렌더링됩니다. 이들은 일부 소품을 받고 일부 UI를 렌더링하는 구성 요소입니다. 이들은 구성 요소 트리의 중간에 앉아있는 구성 요소가 아닙니다 . 데이터 전달, 컨텍스트 설정 등 - 어떤 JavaScript 프레임 워크가 나머지 앱에 전원을 공급하든 상관없이 동일하게 보이는 순수한 UI 조각만이 아닙니다.

우리가 구축하는 웹 구성 요소

버튼과 같이 지루한 (그리고 일반적인) 무언가를 만들기보다는 조금 다른 것을 만들어 봅시다. 마지막 게시물에서 우리는 흐릿한 이미지 미리보기를 사용하여 콘텐츠 리플 로우를 방지하고 이미지가로드되는 동안 사용자에게 알맞은 UI를 제공하는 것을 보았습니다. 우리는 Base64가 모호하고 저하 된 버전의 이미지를 인코딩하고 실제 이미지가로드되는 동안 UI에서이를 보여주는 것을 보았습니다. 또한 Blurhash라는 도구를 사용하여 엄청나게 작고 흐릿한 미리보기를 생성하는 것을 보았습니다.

이 게시물은 해당 미리보기를 생성하여 React 프로젝트에서 사용하는 방법을 보여주었습니다. 이 게시물은 웹 구성 요소에서 해당 미리보기를 사용하여 JavaScript 프레임 워크에서 사용할 수있는 방법을 보여줍니다.

그러나 우리는 달리기 전에 걸어야하므로 웹 구성 요소가 어떻게 작동하는지 정확히보기 위해 먼저 사소하고 어리석은 것을 걸을 것입니다.

이 게시물의 모든 것은 툴링없이 바닐라 웹 구성 요소를 구축합니다. 즉, 코드에는 약간의 상용구가 있지만 따라 가기가 상대적으로 쉽습니다. Lit 또는 Stencil과 같은 도구는 웹 구성 요소를 구축하도록 설계 되었으며이 보일러 플레이트의 대부분을 제거하는 데 사용할 수 있습니다. 나는 당신이 그들을 확인하도록 촉구합니다! 그러나이 게시물에서는 다른 의존성을 도입하고 가르 칠 필요가없는 대가로 약간 더 많은 상용구를 선호합니다.

간단한 카운터 구성 요소

JavaScript 구성 요소의 고전적인 "Hello World"를 만들어 봅시다 : 카운터. 우리는 값과 그 값을 증가시키는 버튼을 렌더링합니다. 단순하고 지루하지만 가능한 가장 간단한 웹 구성 요소를 볼 수 있습니다.

웹 구성 요소를 구축하기 위해 첫 번째 단계는 htmlelement에서 상속되는 JavaScript 클래스를 만드는 것입니다.

 클래스 카운터는 htmlelement {}을 확장합니다.
로그인 후 복사

마지막 단계는 웹 구성 요소를 등록하는 것이지만 아직 등록하지 않은 경우에만 다음과 같습니다.

 if (! customElements.get ( "Counter-WC")) {
  CustomElements.define ( "Counter-WC", Counter);
}
로그인 후 복사

그리고 물론 렌더링하십시오.

 <counter-wc> </counter-wc>
로그인 후 복사

그리고 그 사이의 모든 것은 우리가 웹 구성 요소가 우리가 원하는 모든 것을하는 것입니다. 하나의 일반적인 수명주기 방법은 ConnectedCallback이며 웹 구성 요소가 DOM에 추가 될 때 발사됩니다. 우리는이 방법을 사용하여 원하는 컨텐츠를 렌더링 할 수 있습니다. 이것은 htmlelement의 JS 클래스 상속입니다. 즉, 우리 의이 값은 웹 구성 요소 자체임을 의미하며, 이미 알고 있고 사랑하는 모든 일반적인 DOM 조작 방법이 있습니다.

가장 간단하게, 우리는 이것을 할 수 있습니다.

 클래스 카운터는 htmlelement {
  ConnectedCallback () {
    this.innerhtml = "<div style="'color" : green> hey </div>";
  }
}

if (! customElements.get ( "Counter-WC")) {
  CustomElements.define ( "Counter-WC", Counter);
}
로그인 후 복사

… 잘 작동합니다.

실제 콘텐츠 추가

유용하고 대화식 콘텐츠를 추가해 봅시다. 현재 숫자 값을 유지하려면 카운터를 증가 시키려면 이 필요합니다. 지금은이 컨텐츠를 생성자에 만들어 웹 구성 요소가 실제로 DOM에있을 때 추가 할 것입니다.

 생성자 () {
  감독자();
  const 컨테이너 = document.createElement ( 'div');

  this.valspan = document.createElement ( 'span');

  const icrement = document.createElement ( 'button');
  증분 .innerText = '증분';
  increment.addeventListener ( 'click', () => {
    이것은#value = this.#currentValue 1;
  });

  Container.appendChild (this.valspan);
  container.appendChild (document.createElement ( 'br'));
  컨테이너. AppendChild (증분);

  this.container = 컨테이너;
}

ConnectedCallback () {
  이. AppendChild (this.container);
  this.update ();
}
로그인 후 복사

수동 DOM 생성에 의해 실제로 거칠어지면 InnerHTML을 설정하거나 웹 구성 요소 클래스의 정적 속성으로 한 번 템플릿 요소를 만들고 복제하고 새로운 웹 구성 요소 인스턴스에 대한 내용을 삽입 할 수 있습니다. 내가 생각하지 않는 다른 옵션이있을 것입니다. 또는 항상 Lit 또는 Stencil과 같은 웹 구성 요소 프레임 워크를 사용할 수 있습니다. 그러나이 게시물의 경우 계속 간단하게 유지할 것입니다.

계속해서, 우리는 값이라는 정착식 자바 스크립트 클래스 속성이 필요합니다.

 #currentValue = 0;

set #Value (val) {
  #currentValue = val;
  this.update ();
}
로그인 후 복사

값을 보유 할 두 번째 속성과 함께 세터가있는 표준 클래스 속성 일뿐입니다. 재미있는 트위스트 중 하나는이 값에 대해 개인 자바 스크립트 클래스 속성 구문을 사용한다는 것입니다. 즉, 웹 구성 요소 외부의 어느 누구도 이러한 값을 터치 할 수 없습니다. 이것은 모든 최신 브라우저에서 지원되는 표준 자바 스크립트이므로 사용하는 것을 두려워하지 마십시오.

또는 원하는 경우 _value라고 부르십시오. 그리고 마지막으로 업데이트 방법 :

 업데이트() {
  this.valspan.innertext = this.#currentValue;
}
로그인 후 복사

작동합니다!

분명히 이것은 규모로 유지하려는 코드가 아닙니다. 자세히 살펴 보려면 전체 작업 예가 있습니다. 내가 말했듯이 Lit 및 Stencil과 같은 도구는이를 더 간단하게 만들도록 설계되었습니다.

더 많은 기능을 추가합니다

이 게시물은 웹 구성 요소에 대한 깊은 다이빙이 아닙니다. 우리는 모든 API와 라이프 사이클을 다루지 않을 것입니다. 우리는 그림자 뿌리 나 슬롯도 덮지 않을 것입니다. 그 주제에는 끝없는 내용이 있습니다. 저의 목표는 이미 알고있는 인기있는 JavaScript 프레임 워크와 함께 웹 구성 요소를 실제로 사용하는 데 대한 유용한 지침과 함께 관심을 불러 일으킬 정도로 충분한 소개를 제공하는 것입니다.

이를 위해 카운터 웹 구성 요소를 약간 향상시켜 봅시다. 표시된 값의 색상을 제어하기 위해 색상 속성을 수락하도록합시다. 또한 증분 속성을 수락하도록하겠습니다. 따라서이 웹 구성 요소의 소비자는 한 번에 2, 3, 4 증가 할 수 있습니다. 그리고 이러한 상태 변경을 주도하기 위해 Svelte Sandbox에서 새 카운터를 사용해 보겠습니다. 우리는 조금씩 반응 할 것입니다.

이전과 동일한 웹 구성 요소로 시작하여 색상 속성을 추가하겠습니다. 웹 구성 요소가 속성을 수락하고 응답하도록 웹 구성 요소를 구성하기 위해 웹 구성 요소가 장려하는 속성을 반환하는 정적 관측 attributes 속성을 추가합니다.

 정적 관측 attributes = [ "색상"];
로그인 후 복사

이를 통해 AttributeChangeCallback 라이프 사이클 메소드를 추가 할 수 있습니다. 이는 관찰 된 Attributes에 나열된 속성이 설정되거나 업데이트 될 때마다 실행됩니다.

 AttributeChangedCallback (이름, OldValue, NewValue) {
  if (name === "color") {
    this.update ();
  }
}
로그인 후 복사

이제 업데이트 방법을 업데이트하여 실제로 사용합니다.

 업데이트() {
  this.valspan.innertext = this._currentValue;
  this.valspan.style.color = this.getAttribute ( "color") || "검은색";
}
로그인 후 복사

마지막으로 증분 속성을 추가하겠습니다.

 증분 = 1;
로그인 후 복사

단순하고 겸손합니다.

Svelte에서 카운터 구성 요소 사용

우리가 방금 만든 것을 사용합시다. 우리는 우리의 벨트 앱 구성 요소로 들어가서 다음과 같은 것을 추가 할 것입니다.

 <cript>
  색상 = "빨간색"을하자;
스크립트>


  기본 {
    텍스트 정렬 : 센터;
  }
스타일>


  <bind : value="{color}">를 선택하십시오
     빨간색 옵션>
     녹색 옵션>
     blue 옵션>
  선택>

   
</bind></cript>
로그인 후 복사

그리고 그것은 작동합니다! 카운터는 렌더링, 증분 및 드롭 다운이 색상을 업데이트합니다. 보시다시피, 우리는 Svelte 템플릿에서 색상 속성을 렌더링하고 값이 변경되면 Svelte는 기본 웹 구성 요소 인스턴스에서 setattribute를 호출하는 레그 워크를 처리합니다. 여기에는 특별한 것이 없습니다 : 이것은 HTML 요소의 속성에 대해 이미하는 것과 같습니다.

증분 소품으로 상황이 조금 흥미로워집니다. 이것은 웹 구성 요소의 속성이 아닙니다 . 웹 구성 요소 클래스의 소품입니다. 즉, 웹 구성 요소의 인스턴스에 설정해야합니다. 상황이 훨씬 더 단순 해지므로 나와 함께 견딜 수 있습니다.

먼저, 우리의 벨트 구성 요소에 몇 가지 변수를 추가 할 것입니다.

 증분 = 1;
wcinstance를하자;
로그인 후 복사

카운터 구성 요소의 강국은 1 또는 2로 증가 할 수 있습니다.

  증분 = 1}> 증분 1 
 증분 = 2}> 증분 2 
로그인 후 복사

그러나 이론적으로는 웹 구성 요소의 실제 인스턴스를 가져와야합니다. 이것은 우리가 언제든지 반응에 심판을 추가 할 때마다 항상하는 것과 같습니다. Svelte를 사용하면 간단한 바인드 :이 지침 :

 <coun><p> 이제 Svelte 템플릿에서 구성 요소의 증분 변수의 변경 사항을 듣고 기본 웹 구성 요소 속성을 설정합니다.</p>
<pre rel="JavaScript" data-line=""> $ : {
  if (wcinstance) {
    wcinstance.increment = 증분;
  }
}
로그인 후 복사

이 라이브 데모에서 테스트 할 수 있습니다.

우리는 분명히 관리 해야하는 모든 웹 구성 요소 또는 소품에 대해이 작업을 수행하고 싶지 않습니다. 일반적 으로 구성 요소 소품을 위해하는 것처럼 웹 구성 요소, 마크 업에서 오른쪽으로 씩 증가 할 수 있다면 좋지 않습니까? 다시 말해, 모든 wcinstance 사용을 삭제하고 대신이 더 간단한 코드를 사용할 수 있다면 좋을 것입니다.

 <coun><p> 우리가 할 수있는 것으로 밝혀졌습니다. 이 코드는 작동합니다. Svelte는 우리를 위해 모든 레그 워크를 처리합니다. 이 데모에서 확인하십시오. 이것은 거의 모든 JavaScript 프레임 워크의 표준 동작입니다.</p>
<p> 그렇다면 왜 웹 구성 요소의 소품을 설정하는 수동 방법을 보여 주었습니까? 두 가지 이유 : 이러한 일이 어떻게 작동하는지 이해하는 것이 유용하며, 잠시 전에 이것은 모든 JavaScript 프레임 워크에“거의”작용한다고 말했습니다. 그러나 방금 본 것처럼 웹 구성 요소 소품 설정을 지원하지 않는 하나의 프레임 워크가 있습니다.</p>
<h3> React는 다른 짐승입니다</h3>
<p> 반응. 지구상에서 가장 인기있는 JavaScript 프레임 워크는 웹 구성 요소와의 기본 인터 로프를 지원하지 않습니다. 이것은 반응이 독특한 잘 알려진 문제입니다. 흥미롭게도, 이것은 실제로 React의 실험 지점에 고정되어 있지만 어떤 이유로 든 버전 18으로 병합되지 않았습니다. 즉, 우리는 여전히 진행 상황을 추적 할 수 있습니다. 그리고 당신은 라이브 데모로 직접 시도 할 수 있습니다.</p>
<p> 물론 솔루션은 Ref를 사용하고 웹 구성 요소 인스턴스를 잡고 해당 값이 변경 될 때 수동으로 증가하는 것입니다. 다음과 같이 보입니다.</p>
<pre rel="JSX" data-line=""> import React, {usestate, useref, useeffect} '에서'react ';
import './counter-wc';

내보내기 기본 기능 app () {
  const [증분, setIncrement] = usestate (1);
  const [color, setColor] = usestate ( 'red');
  const wcref = useref (null);

  useeffect (() => {
    wcref.current.increment = 증분;
  }, [증분]);

  반품 (
    <div>
      <div classname="ycrement-container">
         setIncrement (1)}> 1  증가
         setIncrement (2)}> 2  증가
      </div>

       setColor (e.target.value)}>
         빨간색 옵션>
         녹색 옵션>
         blue 옵션>
      선택>

      <coun>
  );
} 라이브 데모<p> 우리가 논의했듯이, 모든 웹 구성 요소 속성에 대해 수동으로 코딩하는 것은 단순히 확장 할 수 없습니다. 그러나 우리는 몇 가지 옵션이 있기 때문에 모두 손실되지 않습니다.</p>
<h4> 옵션 1 : 모든 곳에서 속성을 사용하십시오</h4>
<p> 우리는 속성이 있습니다. 위의 반응 데모를 클릭하면 증분 소품이 작동하지 않지만 색상이 올바르게 변경되었습니다. 속성으로 모든 것을 코딩 할 수 없습니까? 슬프게도, 아니요. 속성 값은 문자열 일 수 있습니다. 그것은 여기서 충분히 좋으며, 우리는이 접근법으로 다소 멀리 갈 수있었습니다. 증분과 같은 숫자는 문자열로 오지서 변환 할 수 있습니다. 우리는 json stringify/parse 객체도 할 수도 있습니다. 그러나 결국 우리는 함수를 웹 구성 요소로 전달해야하며, 그 시점에서 우리는 옵션이 없을 것입니다.</p>
<h4> 옵션 2 : 래핑하십시오</h4>
<p> 간접 수준을 추가하여 컴퓨터 과학에서 문제를 해결할 수 있다는 오래된 말이 있습니다 (너무 많은 수준의 간접의 문제를 제외하고). 이 소품을 설정하는 코드는 예측 가능하고 간단합니다. 도서관에 숨기면 어떨까요? Lit 뒤에있는 똑똑한 사람들은 하나의 해결책을 가지고 있습니다. 이 라이브러리는 웹 구성 요소를 제공 한 후 새로운 React 구성 요소를 작성하고 필요한 속성을 나열합니다. 영리하지만, 나는이 접근법의 팬이 아닙니다.</p>
<p> 수동으로 제작 된 React 구성 요소에 대한 웹 구성 요소를 일대일 매핑하는 대신, 내가 <em>선호</em> 하는 것은 웹 구성 요소 <em>태그 이름을</em> 모든 속성과 속성과 함께 (Coun 제 생각에는 이상적인 해결책입니다. 나는 이것을하는 라이브러리를 모르지만 만들기 위해 간단해야합니다. 샷을하자!</p>
<p> 이것은 우리가 찾고있는 <em>사용법</em> 입니다.</p>
<pre rel="HTML" data-line=""> <wcwrapper wctag="Coun

WCTAG는 웹 구성 요소 태그 이름입니다. 나머지는 우리가 원하는 속성과 속성입니다.

내 구현은 다음과 같습니다.

 import React, {CreateElement, useref, uselayouteffect, memo}의 'React';

const _wcwrapper = (props) => {
  const {wctag, children, ... restprops} = props;
  const wcref = useref (null);

  uselayouteffect (() => {
    const wc = wcref.current;

    for (const.
      if (wc의 키) {
        if (wc [key]! == value) {
          wc [key] = 값;
        }
      } 또 다른 {
        if (wc.getAttribute (key)! == value) {
          wc.setattribute (키, 값);
        }
      }
    }
  });

  return createElement (wctag, {ref : wcref});
};

내보내기 const wcwrapper = 메모 (_wcwrapper);</wcwrapper>
로그인 후 복사

가장 흥미로운 라인은 끝에 있습니다.

 return createElement (wctag, {ref : wcref});
로그인 후 복사

이것이 동적 이름으로 반응하여 요소를 만드는 방법입니다. 실제로, 이것은 JSX를 정상적으로 트랜스 파일로 반응하는 것입니다. 우리의 모든 div는 CreateElement ( "div") 호출로 변환됩니다. 우리는 일반적 으로이 API를 직접 호출 할 필요가 없지만 필요할 때 거기에 있습니다.

그 외에도, 우리는 레이아웃 효과를 실행하고 구성 요소에 전달한 모든 소품을 통해 루프를 원합니다. 우리는 그들 모두를 반복하고 웹 구성 요소 인스턴스 객체와 프로토 타입 체인을 점검하는 확인이있는 속성인지 확인합니다. 그러한 속성이 존재하지 않으면 속성이라고 가정합니다. 두 경우 모두 값이 실제로 변경된 경우에만 설정합니다.

왜 우리가 useeffect 대신 UselayoutEffect를 사용하는지 궁금하다면 컨텐츠가 렌더링되기 전에 이러한 업데이트를 즉시 실행하려고하기 때문입니다. 또한 UselayoutEffect에 대한 종속성 배열이 없습니다. 이것은 우리가 모든 렌더링 에서이 업데이트를 실행하고 싶다는 것을 의미합니다. React가 많이 다시 렌더링하는 경향이 있기 때문에 이것은 위험 할 수 있습니다. 나는 모든 것을 React.Memo로 감싸서 이것을 개선합니다. 이것은 본질적으로 최신 버전의 React.purecomponent입니다. 즉, 구성 요소는 실제 소품 중 하나라도 변경된 경우에만 재 렌더링됩니다. 간단한 평등 점검을 통해 발생했는지 확인합니다.

여기서 유일한 위험은 재 할당하지 않고 직접 돌연변이하는 객체 소품을 전달하는 경우 업데이트가 표시되지 않는다는 것입니다. 그러나 이것은 특히 React 커뮤니티에서 매우 낙담하기 때문에 걱정하지 않을 것입니다.

계속 진행하기 전에 마지막으로 한 가지를 불러 내고 싶습니다. 사용이 어떻게 보이는지에 만족하지 않을 수도 있습니다. 다시,이 구성 요소는 다음과 같이 사용됩니다.

 <wcwrapper wctag="Coun

구체적으로, 웹 구성 요소 태그 이름을 구성 요소로 전달하는 것을 좋아하지 않을 수도 있고 대신 @lit-labs/react 패키지를 선호하여 각 웹 구성 요소에 대한 새로운 개별 반응 구성 요소를 만듭니다. 그것은 완전히 공정하고 당신이 가장 편한 것을 사용하도록 권장합니다. 그러나 나 에게이 접근법의 한 가지 장점은 삭제 하기 쉽다는 것입니다. 일부 기적에 의해 반응이 실험 지점에서 메인 내일로 적절한 웹 구성 요소 처리를 병합하면 위의 코드를 변경할 수 있습니다.

 <wcwrapper wctag="Coun

… 이것에 :

 <coun><p> 아마도 어디에서나 그렇게하기 위해 단일 코드 모드를 작성한 다음 <wcwrapper>를 완전히 삭제할 수도 있습니다. 실제로, 스크래치 : 글로벌 검색과 대체는 아마도 효과가있을 것입니다.</wcwrapper></p>
<h3> 구현</h3>
<p> 알고 있습니다. 기억한다면, 우리의 원래 목표는 마지막 게시물에서 보았던 이미지 미리보기 코드를 가져 와서 웹 구성 요소로 이동하여 JavaScript 프레임 워크에서 사용할 수 있도록하는 것이 었습니다. React의 적절한 인터 로프 부족은 믹스에 많은 세부 사항을 추가했습니다. 그러나 이제 우리는 웹 구성 요소를 만드는 방법에 대한 괜찮은 손잡이를 가지고 있기 때문에 구현은 거의 반 임시적일 것입니다.</p>
<p> 여기에 전체 웹 구성 요소를 떨어 뜨리고 흥미로운 비트를 부를 것입니다. 실제로보고 싶다면 여기에 작업하는 데모가 있습니다. 제가 가장 좋아하는 3 개의 프로그래밍 언어로 제가 가장 좋아하는 세 권의 책 사이를 전환 할 것입니다. 각 책의 URL은 매번 고유하므로 미리보기를 볼 수 있지만 DevTools 네트워크 탭에서 물건을 스로틀하여 실제로 일어나는 일을 볼 수 있습니다.</p>
<details><summary> 전체 코드를보십시오</summary><pre rel="View full code" data-line=""> 클래스 북 커버 확장 htmlelement {
  정적 관측 attributes = [ 'url'];

  AttributeChangedCallback (이름, OldValue, NewValue) {
    if (name === 'url') {
      this.createmainimage (newValue);
    }
  }

  미리보기 세트 (val) {
    this.previewel = this.createPreview (val);
    this.render ();
  }

  CreatePreview (val) {
    if (typeof val === 'string') {
      Return Base64preview (Val);
    } 또 다른 {
      return blurhashpreview (val);
    }
  }

  CreateMainImage (url) {
    this.loaded = false;
    const img = document.createElement ( 'IMG');
    img.alt = '책 표지';
    img.addeventListener ( 'load', () = & gt; {
      if (img === this.imageel) {
        this.loaded = true;
        this.render ();
      }
    });
    img.src = url;
    this.imageel = img;
  }

  ConnectedCallback () {
    this.render ();
  }

  렌더 () {
    const elementmaybe = this.loaded? this.imageel : this.previewel;
    SyncsingLechild (this, emectmaybe);
  }
}
로그인 후 복사

먼저, 우리는 관심있는 속성을 등록하고 변경할 때 반응합니다.

 정적 관측 attributes = [ 'url'];

AttributeChangedCallback (이름, OldValue, NewValue) {
  if (name === 'url') {
    this.createmainimage (newValue);
  }
}
로그인 후 복사

이로 인해 이미지 구성 요소가 생성되며로드 된 경우에만 표시됩니다.

 CreateMainImage (url) {
  this.loaded = false;
  const img = document.createElement ( 'IMG');
  img.alt = '책 표지';
  img.addeventListener ( 'load', () => {
    if (img === this.imageel) {
      this.loaded = true;
      this.render ();
    }
  });
  img.src = url;
  this.imageel = img;
}
로그인 후 복사

다음으로 Base64 미리보기 문자열 또는 Blurhash 패킷이 될 수있는 미리보기 속성이 있습니다.

 미리보기 세트 (val) {
  this.previewel = this.createPreview (val);
  this.render ();
}

CreatePreview (val) {
  if (typeof val === 'string') {
    Return Base64preview (Val);
  } 또 다른 {
    return blurhashpreview (val);
  }
}
로그인 후 복사

이것은 우리가 필요한 도우미 기능을 방어합니다.

 함수 base64preview (val) {
  const img = document.createElement ( 'IMG');
  img.src = val;
  반환 IMG;
}

함수 blurhashpreview (미리보기) {
  const canvasel = document.createelement ( 'canvas');
  const {w : 너비, H : 높이} = 미리보기;

  canvasel.width = 너비;
  Canvasel.height = 높이;

  const pixels = decode (preview.blurhash, 너비, 높이);
  const ctx = canvasel.getContext ( '2d');
  const imageata = ctx.createimagedata (너비, 높이);
  imagedata.data.set (픽셀);
  ctx.putImagedata (Imagedata, 0, 0);

  반환 캔버셀;
}
로그인 후 복사

그리고 마지막으로, 우리의 렌더 방법 :

 ConnectedCallback () {
  this.render ();
}

렌더 () {
  const elementmaybe = this.loaded? this.imageel : this.previewel;
  SyncsingLechild (this, emectmaybe);
}
로그인 후 복사

그리고 모든 것을 하나로 묶는 몇몇 도우미 방법 :

 내보내기 기능 동기화 리드 (컨테이너, 아동) {
  const currentchild = container.firstelementchild;
  if (currentchild! == child) {
    ClearContainer (컨테이너);
    if (child) {
      컨테이너. AppendChild (자식);
    }
  }
}

내보내기 기능 ClearContainer (el) {
  자녀를 두십시오.

  while ((child = el.firstelementchild)) {
    el.RemoveChild (자녀);
  }
}
로그인 후 복사

프레임 워크에서 이것을 구축하는 경우 필요한 것보다 조금 더 많은 보일러 플레이트이지만, 우리가 원하는 프레임 워크에서 이것을 재사용 할 수 있다는 것입니다. 그러나 React는 논의한대로 지금 래퍼가 필요합니다.

잡동사니

나는 이미 Lit의 React Wrapper를 언급했습니다. 그러나 스텐실을 사용하는 경우 실제로 React를 위해 별도의 출력 파이프 라인을 지원합니다. 그리고 Microsoft의 좋은 사람들은 Fast Web Component Library에 첨부 된 Lit의 래퍼와 비슷한 것을 만들었습니다.

앞서 언급했듯이 React라는 이름이 아닌 모든 프레임 워크는 귀하를 위해 웹 구성 요소 속성을 설정합니다. 일부는 구문의 특별한 맛이 있습니다. 예를 들어, solid.js를 사용하면 항상 값이 속성이라고 가정합니다.

마무리

웹 구성 요소는 종종 웹 개발 환경의 흥미롭고 부족한 부분입니다. UI 또는 "리프"구성 요소를 관리하여 단일 JavaScript 프레임 워크에 대한 의존도를 줄이는 데 도움이 될 수 있습니다. Svelte 또는 React 구성 요소와 달리 웹 구성 요소로이를 작성하는 동안 인체 공학적이지 않지만 상승은 널리 재사용 할 수 있다는 것입니다.

위 내용은 상호 운용 가능한 웹 구성 요소 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 추천
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿