This article provides a primer on some of the basic concepts of Web Components, as well as some simple examples for your reference. (Also: this article refers to Web Components in MDN. For more information, click on the Magic Portal.)
Getting Started – This article
- What is the problem that Web Components is trying to solve?
- Composition of Web Components.
- Hello World for Web Components
- Web Components lifecycle
- Template and slot for Web Components
- CSS style isolation for Web Components
Advanced. – Next one
- Web Componets Base library lit-Element
- How do Web Components work with modern frameworks such as React
- How Web Components lets users customize their styles (set from outside webComponents)
What is the problem that Web Components is trying to solve?
A quote from the concept and usage section of the official website:
As developers, we all know it’s a good idea to reuse as much code as possible. This is often not so easy for custom tag structures — think of complex HTML (and associated styles and scripts), sometimes you have to write code to render custom UI controls, and using them multiple times can mess up your pages if you’re not careful.
Well, tell me what I understand. In business terms, writing a front end is writing a bunch of business-friendly components and putting them together. The way we use it now, whether we use VUE or React, our original intention, which I think is very important, is to make it easy for developers to create custom components, and use the features of MVVM to manage our business logic, achieve as much separation of view logic as possible, and make our components easy to reuse. Vue and React are the community’s answer, while Web Components feels like the official answer. The JS API makes it easy to create custom components that are easy to reuse and can coexist with the existing framework without worrying about conflicts with existing code.
Not conflicting with the original code is very strong, I realize, this seems to solve the CSS conflict problem, the problem of the century. For the styled components, however, we use them quite well now. However, for some older projects, such as the use of Boostrap library, there is a global style intrusion, when you want to use a component library like ANTD, there are likely to be some unexpected problems in the process of use, always affect your usage expectation.
So look at the pros:
-
Support for Web Components is advancing rapidly across browser platforms
-
Provides a way to customize styles based on design token-friendly styles
-
CSS shadow DOM isolation brings convenience
I think Web Components is the answer to a comprehensive problem that addresses front-end development pain points. As for the good and bad, I hope my article can give you some help.
That’s the background. Let’s get to the subject.
Composition of Web Components
The core concepts of Web Components are three:
- Custom Elements: This is the core, we can define the element behavior through the JS API, and then use it when we use it. (My understanding is that this provides a base class that provides some basic capabilities, such as event registration.)
- Second, we can isolate the DOM from the rest of the page, keeping element functionality private. (This is very useful, CSS private really recommended, but does it have some problems, such as fonts, which need to be set globally, should we not need to redefine in the component layer?)
- Html Templates: Templates and slot tags are provided so that you can write and reuse your components flexibly.
These three are the basic concepts of understanding Web Components. The Custom Element provides a JS API that allows usto define the basic behavior of complex interactions between components. The Shadow DOM allows usto truly have a Custom component, isolated from the original DOM structure, so that our components can have the desired style. HTML Templates provides flexible templates and slots that allow you to write more powerful and reusable components.
Hello World for Web Components
It’s cheesy, but this has to be there
web components
class HelloWorld extends HTMLElement {
constructor() {
// The super method must be called first to inherit from the base class
super(a);// Initialize the Web Component
this.init();
}
init() {
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('span');
wrapper.innerHTML = "Hello World.";
shadow.appendChild(wrapper);
}
}
customElements.define('hello-world', HelloWorld);
/ / use
<hello-world />
// Here is the HTML structure of render
Copy the code
To explain the code a little bit, we created a custom class HelloWorld based on HTMLElement. Call the super method to get the base class capability, and here I perform an initialization method init(). In init we do these things:
- Create a shadow-root element node based on attachShadow on the base class
- You also create a SPAN element with the content Hello World
- Append the SPAN element to the shadow element
- To use customElements. Define, register the custom event. Then you can use it directly
- Custom Elements are created in two ways
- Built-in: you can extend existing HTML elements by using is=”custom name”
- The custom
- For customElements. Define, note the naming conventions for customElements
- A DOMString string representing the name of the element being created. Note that the name of a Custom Element cannot be a single word and must have a dash.
- A class that defines the behavior of an element.
Optional parameters
, one containsextends
Property. This parameter is optional. It specifies which built-in element the created element inherits from, and can inherit from any built-in element.
- Custom Elements are created in two ways
This is a simple example of how to use the Web Component. We also touched on custom Elements and the Shadow DOM. That’s our first step, Hello World.
Web Components lifecycle
Surprise, shadow DOM also has a life cycle. The life cycle consists of the following four:
- ConnectedCallback: Called when a Custom Element is first inserted into the document DOM.
- DisconnectedCallback: Called when a Custom Element is removed from the DOM of the document.
- AdoptedCallback: Called when a Custom Element is moved to a new document.
- AttributeChangedCallback: Called when a Custom Element adds, deletes, or modifies its attributes.
class HelloWorld extends HTMLElement {
constructor() {
// The super method must be called first to inherit from the base class
super(a);// Initialize the Web Component
this.init();
}
connectedCallback() {
console.log("connectedCallback.");
}
disconnectedCallback() {
console.log("disconnectedCallback.");
}
adoptedCallback(){
console.log("adoptedCallback.");
}
attributeChangedCallback(name, oldValue, newValue) {
console.log("attributeChangedCallback. change " + name + "value is" + newValue + "old Value is" + oldValue);
}
init() {
var shadow = this.attachShadow({mode: 'open'});
var wrapper = document.createElement('span');
wrapper.innerHTML = "Hello World.";
shadow.appendChild(wrapper);
}
}
customElements.define('hello-world', HelloWorld);
document.body.append(document.createElement("hello-world"));
Copy the code
There’s nothing to say about this cycle, except that disconnectedCallback can listen for property changes when it enters, when it exits, when it disconnectedCallback.
Template and slot for Web Components
template
Template and slot we’ve already touched on when we used VUE. However, this template is quite different from the one in Vue. Let’s take a look at a usage example:
<template id="template">
<style>
p {
color: white;
background-color: # 666;
padding: 5px;
}
</style>
<p>
Halo template
</p>
</template>
Copy the code
If we insert this HTML in the page, the corresponding P tag will not be displayed on the page. Until you get the DOM by id and add it to the DOM tree, the template takes effect:
let template = document.querySelector("#template");
let templateContent = template.content;
document.body.appendChild(templateContent);
Copy the code
Use template with Web Components:
customElements.define('custom-p'.class extends HTMLElement {
constructor() {
super(a);let template = document.querySelector('template');
let templateContent = template.content;
const shadowRoot = this.attachShadow({mode: 'open'})
.appendChild(templateContent.cloneNode(true)); }})Copy the code
slot
Provides greater flexibility. Based on the example above:
<template id="template">
<style>
p {
color: white;
background-color: # 666;
padding: 5px;
}
</style>
<p>
Halo template <slot name="name"></slot>
</p>
</template>
Copy the code
Then we can use it like this:
<custom-p>
<span slot="name">hawei</span>
</custom-p>
Copy the code
CSS style isolation for Web Components
Finally, this is the most important property. As we discussed earlier why Web Components appear, the Shadow DOM is rendered separately from the DOM in our page, thus achieving style isolation. This point we can review the browser render process. I won’t repeat it here. Here’s an example:
class HelloWorld extends HTMLElement {
constructor() {
// The super method must be called first to inherit from the base class
super(a);this.shadow = this.attachShadow({mode: 'open'});
// Initialize the Web Component
this.init();
}
init() {
this.addStyle();
this.addNode();
}
addNode() {
const wrapper = document.createElement('span');
wrapper.className = "hawei1"
wrapper.innerHTML = "Hello World1.";
const wrapper1 = document.createElement('span');
wrapper1.className = "hawei2"
wrapper1.innerHTML = "Hello World2.";
this.shadow.appendChild(wrapper);
this.shadow.appendChild(wrapper1);
}
addStyle() {
const styleDom = document.createElement("style");
styleDom.textContent = ` .hawei1 { color: orange; } `;
this.shadow.appendChild(styleDom);
}
}
customElements.define('hello-world', HelloWorld);
function renderDom() {
document.body.innerHTML=`
hawei
hawei2
`;
}
renderDom();
document.body.append(document.createElement("hello-world"));
Copy the code
As you can see, in renderDom we created two divs and gave the classes hawei1 and hawei2. In shadow DOM, I also created two span elements and gave the classes hawei1 and hawei2. And give different color styles at the same time. Render results as follows:
As you can see, the styles in the renderDom and the styles in the shadow DOM do not affect each other. I think that’s a big selling point for Web Components. Styled – Components can also solve this problem, but random string generation is also performance required. And this official solution I think solves the problem from an architectural point of view.
Hum, hum, hum, hum, hum, hum.
reference
-
MDN Web Components section
-
chromedevsummit web components