Dansk

Udforsk kraften i Web Components med fokus på Custom Elements til at bygge genanvendelige og indkapslede UI-komponenter til forskellige webapplikationer.

Web Components: Et dybdegående kig på Custom Elements

Web Components repræsenterer et markant fremskridt inden for webudvikling og tilbyder en standardiseret måde at skabe genanvendelige og indkapslede UI-komponenter. Blandt de kerneteknologier, der udgør Web Components, fremstår Custom Elements som hjørnestenen for at definere nye HTML-tags med tilpasset adfærd og gengivelse. Denne omfattende guide dykker ned i finesserne ved Custom Elements og udforsker deres fordele, implementering og bedste praksis for at bygge moderne webapplikationer.

Hvad er Web Components?

Web Components er et sæt webstandarder, der giver udviklere mulighed for at skabe genanvendelige, indkapslede og interoperable HTML-elementer. De tilbyder en modulær tilgang til webudvikling, hvilket muliggør oprettelsen af tilpassede UI-komponenter, der let kan deles og genbruges på tværs af forskellige projekter og frameworks. Kerneteknologierne bag Web Components inkluderer:

Forståelse af Custom Elements

Custom Elements er kernen i Web Components og gør det muligt for udviklere at udvide HTML-vokabularet med deres egne elementer. Disse tilpassede elementer opfører sig som standard HTML-elementer, men de kan skræddersys til specifikke applikationsbehov, hvilket giver større fleksibilitet og kodeorganisering.

Definition af Custom Elements

For at definere et custom element skal du bruge metoden customElements.define(). Denne metode tager to argumenter:

  1. Elementets navn: En streng, der repræsenterer navnet på det tilpassede element. Navnet skal indeholde en bindestreg (-) for at undgå konflikter med standard HTML-elementer. For eksempel er my-element et gyldigt navn, mens myelement ikke er det.
  2. Elementets klasse: En JavaScript-klasse, der udvider HTMLElement og definerer adfærden for det tilpassede element.

Her er et grundlæggende eksempel:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.innerHTML = 'Hello, World!';
  }
}

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

I dette eksempel definerer vi et custom element ved navn my-element. Klassen MyElement udvider HTMLElement og sætter elementets indre HTML til "Hello, World!" i konstruktøren.

Custom Element Livscyklus-Callbacks

Custom elements har flere livscyklus-callbacks, der giver dig mulighed for at udføre kode på forskellige stadier af elementets livscyklus. Disse callbacks giver mulighed for at initialisere elementet, reagere på attributændringer og rydde op i ressourcer, når elementet fjernes fra DOM'en.

Her er et eksempel, der demonstrerer brugen af livscyklus-callbacks:

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

  connectedCallback() {
    this.shadow.innerHTML = `

Connected to the DOM!

`; console.log('Element connected'); } disconnectedCallback() { console.log('Element disconnected'); } static get observedAttributes() { return ['data-message']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'data-message') { this.shadow.innerHTML = `

${newValue}

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

I dette eksempel logger connectedCallback() en besked til konsollen og sætter elementets indre HTML, når det er forbundet til DOM'en. disconnectedCallback() logger en besked, når elementet afbrydes. attributeChangedCallback() kaldes, når data-message-attributten ændres, og opdaterer elementets indhold i overensstemmelse hermed. observedAttributes-getteren specificerer, at vi ønsker at observere ændringer i data-message-attributten.

Brug af Shadow DOM til indkapsling

Shadow DOM giver indkapsling til webkomponenter, hvilket giver dig mulighed for at oprette et separat DOM-træ for en komponent, der er isoleret fra resten af siden. Det betyder, at stilarter og scripts defineret inden for Shadow DOM ikke vil påvirke resten af siden, og omvendt. Denne indkapsling hjælper med at forhindre konflikter og sikrer, at dine komponenter opfører sig forudsigeligt.

For at bruge Shadow DOM kan du kalde attachShadow()-metoden på elementet. Denne metode tager et options-objekt, der specificerer tilstanden for Shadow DOM. mode kan være enten 'open' eller 'closed'. Hvis tilstanden er 'open', kan Shadow DOM tilgås fra JavaScript ved hjælp af elementets shadowRoot-egenskab. Hvis tilstanden er 'closed', kan Shadow DOM ikke tilgås fra JavaScript.

Her er et eksempel, der demonstrerer brugen af Shadow DOM:

class MyElement extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
    this.shadow.innerHTML = `
      
      

This is inside the Shadow DOM.

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

I dette eksempel vedhæfter vi en Shadow DOM til elementet med mode: 'open'. Vi sætter derefter den indre HTML i Shadow DOM til at inkludere en stil, der sætter farven på afsnit til blå, og et afsnitselement med noget tekst. Stilen, der er defineret inden for Shadow DOM, vil kun gælde for elementer inden for Shadow DOM og vil ikke påvirke afsnit uden for Shadow DOM.

Fordele ved at bruge Custom Elements

Custom Elements tilbyder flere fordele for webudvikling:

Praktiske eksempler på Custom Elements

Lad os udforske nogle praktiske eksempler på, hvordan Custom Elements kan bruges til at bygge almindelige UI-komponenter.

En simpel tællerkomponent

Dette eksempel viser, hvordan man opretter en simpel tællerkomponent ved hjælp af Custom Elements.

class Counter extends HTMLElement {
  constructor() {
    super();
    this.shadow = this.attachShadow({ mode: 'open' });
    this._count = 0;
    this.render();
  }

  connectedCallback() {
    this.shadow.querySelector('.increment').addEventListener('click', () => {
      this.increment();
    });
    this.shadow.querySelector('.decrement').addEventListener('click', () => {
      this.decrement();
    });
  }

  increment() {
    this._count++;
    this.render();
  }

  decrement() {
    this._count--;
    this.render();
  }

  render() {
    this.shadow.innerHTML = `
      
      
${this._count}
`; } } customElements.define('my-counter', Counter);

Denne kode definerer en Counter-klasse, der udvider HTMLElement. Konstruktøren initialiserer komponenten, vedhæfter en Shadow DOM og sætter den indledende tællerværdi til 0. connectedCallback()-metoden tilføjer event listeners til forøgelses- og formindskelsesknapperne. Metoderne increment() og decrement() opdaterer tælleren og kalder render()-metoden for at opdatere komponentens gengivelse. render()-metoden sætter den indre HTML i Shadow DOM til at inkludere tællerdisplayet og knapperne.

En billedkarruselkomponent

Dette eksempel viser, hvordan man opretter en billedkarruselkomponent ved hjælp af Custom Elements. For korthedens skyld er billedkilderne pladsholdere og kunne indlæses dynamisk fra et API, et CMS eller lokal lagring. Stylingen er også blevet minimeret.

class ImageCarousel extends HTMLElement {
 constructor() {
  super();
  this.shadow = this.attachShadow({ mode: 'open' });
  this._images = [
  'https://via.placeholder.com/350x150',
  'https://via.placeholder.com/350x150/0077bb',
  'https://via.placeholder.com/350x150/00bb77',
  ];
  this._currentIndex = 0;
  this.render();
 }

 connectedCallback() {
  this.shadow.querySelector('.prev').addEventListener('click', () => {
  this.prevImage();
  });
  this.shadow.querySelector('.next').addEventListener('click', () => {
  this.nextImage();
  });
 }

 nextImage() {
  this._currentIndex = (this._currentIndex + 1) % this._images.length;
  this.render();
 }

 prevImage() {
  this._currentIndex = (this._currentIndex - 1 + this._images.length) % this._images.length;
  this.render();
 }

 render() {
  this.shadow.innerHTML = `
  
  
  `;
 }
}

customElements.define('image-carousel', ImageCarousel);

Denne kode definerer en ImageCarousel-klasse, der udvider HTMLElement. Konstruktøren initialiserer komponenten, vedhæfter en Shadow DOM og indstiller det indledende billedarray og det aktuelle indeks. connectedCallback()-metoden tilføjer event listeners til forrige- og næste-knapperne. Metoderne nextImage() og prevImage() opdaterer det aktuelle indeks og kalder render()-metoden for at opdatere komponentens gengivelse. render()-metoden sætter den indre HTML i Shadow DOM til at inkludere det aktuelle billede og knapperne.

Bedste praksis for at arbejde med Custom Elements

Her er nogle bedste praksisser, du kan følge, når du arbejder med Custom Elements:

Custom Elements og Frameworks

Custom Elements er designet til at være interoperable med andre webteknologier og frameworks. De kan bruges i forbindelse med populære frameworks som React, Angular og Vue.js.

Brug af Custom Elements i React

For at bruge Custom Elements i React kan du simpelthen gengive dem som ethvert andet HTML-element. Dog kan det være nødvendigt at bruge en ref for at få adgang til det underliggende DOM-element og interagere direkte med det.

import React, { useRef, useEffect } from 'react';

function MyComponent() {
  const myElementRef = useRef(null);

  useEffect(() => {
    if (myElementRef.current) {
      // Access the custom element's API
      myElementRef.current.addEventListener('custom-event', (event) => {
        console.log('Custom event modtaget:', event.detail);
      });
    }
  }, []);

  return ;
}

export default MyComponent;

I dette eksempel bruger vi en ref til at få adgang til my-element custom elementet og tilføjer en event listener til det. Dette giver os mulighed for at lytte efter custom events, der afsendes af det tilpassede element, og reagere i overensstemmelse hermed.

Brug af Custom Elements i Angular

For at bruge Custom Elements i Angular skal du konfigurere Angular til at genkende det tilpassede element. Dette kan gøres ved at tilføje det tilpassede element til schemas-arrayet i modulets konfiguration.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent],
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AppModule { }

Når det tilpassede element er registreret, kan du bruge det i dine Angular-skabeloner som ethvert andet HTML-element.

Brug af Custom Elements i Vue.js

Vue.js understøtter også Custom Elements native. Du kan bruge dem direkte i dine skabeloner uden nogen speciel konfiguration.



Vue vil automatisk genkende det tilpassede element og gengive det korrekt.

Overvejelser om tilgængelighed

Når man bygger Custom Elements, er det afgørende at overveje tilgængelighed for at sikre, at dine komponenter kan bruges af alle, inklusive personer med handicap. Her er nogle centrale overvejelser om tilgængelighed:

Internationalisering og lokalisering

Når du udvikler Custom Elements til et globalt publikum, er det vigtigt at overveje internationalisering (i18n) og lokalisering (l10n). Her er nogle centrale overvejelser:

Konklusion

Custom Elements er et kraftfuldt værktøj til at bygge genanvendelige og indkapslede UI-komponenter. De tilbyder flere fordele for webudvikling, herunder genanvendelighed, indkapsling, interoperabilitet, vedligeholdelighed og ydeevne. Ved at følge de bedste praksisser, der er beskrevet i denne guide, kan du udnytte Custom Elements til at bygge moderne webapplikationer, der er robuste, vedligeholdelige og tilgængelige for et globalt publikum. Efterhånden som webstandarder fortsætter med at udvikle sig, vil Web Components, herunder Custom Elements, blive stadig vigtigere for at skabe modulære og skalerbare webapplikationer.

Omfavn kraften i Custom Elements for at bygge fremtidens web, én komponent ad gangen. Husk at overveje tilgængelighed, internationalisering og lokalisering for at sikre, at dine komponenter kan bruges af alle, overalt.

Web Components: Et dybdegående kig på Custom Elements | MLOG