当前位置:网站首页>[web technology] 1233 seconds understand web component
[web technology] 1233 seconds understand web component
2022-07-02 17:22:00 【pingan8787】
What is it?
Web Components In fact, a combination of a series of technologies , It mainly includes 3 part :
Custom elements . stay HTML Extend custom label elements beyond the basic label
Shadow DOM. Mainly used to Shadow DOM Content and outer layer of document DOM Isolation
HTML Templates . Use
<template>To define component templates , Use<slot>Use as a slot
It is precisely because it is a series of API The combination of , So in use , We need to focus on these at the same time API The compatibility of :



After using the above technology reasonably , Can Will function 、 Custom logic is encapsulated in the tag , Improve development efficiency by reusing these custom components . It sounds like Vue.js and React The one you made , actually , In the use of Web Components When , It's also very similar .
Get started
Next, we implement a <book-card> Web Component Let's learn how to use it .

Custom elements
First , Create a index.html, Call directly inside <book-card> Components .
<body>
<book-card></book-card>
<script src="./BookCard.js"></script>
</body> Because browsers don't know <book-card> therefore , We need to be in BookCard.js Register it in , And in index.html Introduce and execute BookCard.js.
class BookCard extends HTMLElement {
constructor() {
super();
const container = document.createElement('div')
container.className = 'container'
const image = document.createElement('img')
image.className = 'image'
image.src = "https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp"
const title = document.createElement('p')
title.className = 'title'
title.textContent = ' The sacrifice of Chernobyl '
const desc = document.createElement('p')
desc.className = 'desc'
desc.textContent = 'S·A· Alexeyevich '
const price = document.createElement('p')
price.className = 'price'
price.textContent = `¥25.00`
container.append(image, title, desc, price)
this.appendChild(container)
}
}
customElements.define('book-card', BookCard)The above has realized the most basic DOM It's structured :

The above has been executing
createElementAnd set whether the behavior of the attribute value is a bit like React OfReact.createElementWell ?
HTML Templates
This generates... Line by line DOM The structure is not only tired of writing , It is also difficult for readers to understand at once . To solve this problem , We can use HTML Templates . Directly in HTML There's a <template> Templates :
<body>
<template id="book-card-template">
<div class="container">
<img class="image" src="https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp" alt="">
<p class="title"> The sacrifice of Chernobyl </p>
<p class="desc">S·A· Alexeyevich </p>
<p class="price">¥25.00</p>
</div>
</template>
<book-card></book-card>
<script src="BookCard.js"></script>
</body>Then call this template directly in the registration component :
class BookCard extends HTMLElement {
constructor() {
super();
const templateElem = document.getElementById('book-card-template')
const clonedElem = templateElem.content.cloneNode(true)
this.appendChild(clonedElem)
}
}
customElements.define('book-card', BookCard)In this way
<template>Is the writing style a little like what we are familiar withVueIt's framed ?
Writing style
done DOM after , Then we can write the style , Directly in <template> Add a new one to it <style> Elements , Then start writing CSS:
<body>
<template id="book-card-template">
<style>
p { margin: 0 }
.container { display: inline-flex; flex-direction: column; border-radius: 6px; border: 1px solid silver; padding: 16px; margin-right: 16px }
.image { border-radius: 6px; }
.title { font-weight: 500; font-size: 16px; line-height: 22px; color: #222; margin-top: 14px; margin-bottom: 9px; }
.desc { margin-bottom: 12px; line-height: 1; color: #8590a6; font-size: 14px; }
.price { color: #8590a6; font-size: 14px; }
</style>
<div class="container">
<img class="image" src="https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp" alt="">
<p class="title"> The sacrifice of Chernobyl </p>
<p class="desc">S·A· Alexeyevich </p>
<p class="price">¥25.00</p>
</div>
</template>
<book-card></book-card>
<script src="BookCard.js"></script>
</body>I believe everyone will write like this CSS, So in order to reduce the length, we put CSS It's folded , The final effect is as follows :

Shadow DOM
In order not to let <template> Inside <style> CSS And the overall situation CSS There are conflicts , We can hang the components to Shadow Root On , Reuse Shadow Root Hanging on the outer layer document DOM On , In this way... Can be achieved CSS Isolation of :
class BookCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' })
const templateElem = document.getElementById('book-card-template')
const clonedElem = templateElem.content.cloneNode(true)
this.shadowRoot.appendChild(clonedElem)
}
}
customElements.define('book-card', BookCard) Open console , You can see <template> Of DOM All hung up on Shadow Root Yes :

Whole DOM The architecture is roughly like this :

Shadow DOM One of the great advantages of is the ability to DOM structure 、 style 、 Behavior and Document DOM To separate from each other , It is very suitable for packaging components , So it can be Web Component An important part of .
Shadow DOM It often appears in our daily development , such as <video> In the element controls Control DOM The structure is also hung on Shadow Root Under the :

Props
and Vue and React The components are the same , We can also do that Web Component Pass attributes on :
<body>
<template id="book-card-template">
<style>
...
</style>
<div class="container">
<img class="image" src="" alt="">
<p class="title"></p>
<p class="desc"></p>
<p class="price"></p>
</div>
</template>
<book-card
data-image="https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp"
data-title=" The sacrifice of Chernobyl "
data-desc="S·A· Alexeyevich "
data-price="25.00"
></book-card>
<script src="BookCard.js"></script>
</body>Then update these properties to DOM On :
const prefix = 'data-'
class BookCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' })
const templateElem = document.getElementById('book-card-template')
const clonedElem = templateElem.content.cloneNode(true)
clonedElem.querySelector('.container > .image').src = this.getAttribute(`${prefix}image`)
clonedElem.querySelector('.container > .title').textContent = this.getAttribute(`${prefix}title`)
clonedElem.querySelector('.container > .desc').textContent = this.getAttribute(`${prefix}desc`)
clonedElem.querySelector('.container > .price').textContent = `¥${this.getAttribute(`${prefix}price`)}`
this.shadowRoot.appendChild(clonedElem)
}
}
customElements.define('book-card', BookCard) Generally speaking , For custom properties , We are used to using data-xxx Named after the .
If you can think further , You can get these directly
attributes, Then use it to do Proxy agent 、 Responsive assignment and other operations . Um. , Yes Vue It's too delicious !
const prefix = 'data-'
const attrList = Array.from(this.attributes);
const props = attrList.filter(attr => attr.name.startsWith(prefix))
// monitor props
watch(props)Slot
HTML Another advantage of templates is that they can be like Vue The use of <slot>. such as , Now we can be here <book-card> Add a... At the bottom action slot :
<template id="book-card-template">
<style>
...
</style>
<div class="container">
<img class="image" src="" alt="">
<p class="title"></p>
<p class="desc"></p>
<p class="price"></p>
<div class="action">
<slot name="action-btn"></slot>
</div>
</div>
</template> When others want to use <book-card> When the component , You can use them through slots and inject their customized content :
<book-card
data-image="https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp"
data-title=" The sacrifice of Chernobyl "
data-desc="S·A· Alexeyevich "
data-price="25.00"
>
<button slot="action-btn" class="btn primary"> Buy </button>
</book-card>
<book-card
data-image="https://pic1.zhimg.com/50/v2-a6d65e05ec8db74369f3a7c0073a227a_200x0.webp"
data-title=" The sacrifice of Chernobyl "
data-desc="S·A· Alexeyevich "
data-price="25.00"
>
<button slot="action-btn" class="btn danger"> Delete </button>
</book-card>
Interaction
We can still be like React Bind events to elements like that , For example, here for this action <slot> Add click event :
class BookCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open' })
const templateElem = document.getElementById('book-card-template')
const clonedElem = templateElem.content.cloneNode(true)
...
clonedElem.querySelector('.container > .action').addEventListener('click', this.onAction)
this.shadowRoot.appendChild(clonedElem)
}
onAction = () => {
alert('Hello World')
}
}
Be careful : there onAction Is the arrow function , Because you need to bind this, Point it to this BookCard Components .
UI library
Maybe some students have begun to think : Since this thing can be used to encapsulate components , There is a corresponding Web Component UI The library? ? The answer is yes .
At present, there are some famous products produced by Microsoft FAST[2]:

Yes Google Produced Lit[3]:

And Tencent of our factory OMI[4]:

summary
The above mainly shares with you Web Component Some usage methods . in general ,Web Component Is a series of API The combination of :
Custom Element: Register and use components
Shadow DOM: Isolation CSS
HTML template and slot: agile DOM structure
About Web Component The content of , It's almost finished , I don't know how you feel after reading . It gives me the feeling that it provides the function of native component encapsulation , But there are a lot of things not done , For example, what we want to see :
image Vue That kind of responsive tracking of data
image Vue That kind of template syntax 、 Data binding
image React Like that DOM Diff
image React Like that
React.createElementOf JSX How to write it...
These are what we hope “ Frame features ” Web Component Are not provided . This is because Web Component All the contents are made by API form , And these API As a specification, keep the function single 、 The principle of orthogonality , Instead of acting like Vue, React Such componentization “ frame ”. I know that, too 《Web Component And the class React、Angular、Vue Who will become the future of component technology ?》[5] The answer said :
The responsibility of the framework is to provide a complete set of solutions , And the platform API The design requirement of is never to provide a complete set of solutions ( That is to ensure zero coupling 、 orthogonal ), This is the fundamental contradiction that cannot be reconciled .
Web Component The main benefit is native support 、 No external dependence . One index.html + main.js You can complete the component registration and use .
at present , It's still developing , It can also be used in production environments , image single-spa Layout Engine as well as MicroApp It's an example , Another scenario is that you can TextArea, Video Such functional components are used in Web Component To encapsulate .
Reference material
[1]
Project code : https://github.com/haixiangyan/bookcard-web-component
[2]FAST: https://www.fast.design/
[3]Lit: https://lit.dev/
[4]OMI: https://tencent.github.io/omi/
[5]《Web Component And the class React、Angular、Vue Who will become the future of component technology ?》: https://www.zhihu.com/question/58731753/answer/158331367

1. JavaScript Revisit the series (22 Complete )
2. ECMAScript Revisit the series (10 Complete )
3. JavaScript Design patterns Revisit the series (9 Complete )
4. Regular / frame / Algorithm etc. Revisit the series (16 Complete )
5. Webpack4 introduction ( On )|| Webpack4 introduction ( Next )
6. MobX introduction ( On ) || MobX introduction ( Next )
7. 120+ Summary of original series

reply “ Add group ” Communicate and learn with the big guys ~
Click on “ Read the original ” see 130+ Original articles
边栏推荐
- Eth data set download and related problems
- Deep learning image data automatic annotation [easy to understand]
- AP and F107 data sources and processing
- Ap和F107数据来源及处理
- 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
- 13、Darknet YOLO3
- 几行代码搞定RPC服务注册和发现
- IDEA2021.1 安装教程
- The computer comes with software to make the background color of the picture transparent (matting white background)
- Weili holdings listed on the Hong Kong Stock Exchange: with a market value of HK $500million, it contributed an IPO to Hubei
猜你喜欢

Sword finger offer 22 The penultimate node in the linked list

深度之眼(二)——矩阵及其基本运算

如何与博格华纳BorgWarner通过EDI传输业务数据?

Qstype implementation of self drawing interface project practice (II)

畅玩集团冲刺港股:年营收2.89亿 刘辉有53.46%投票权

綠竹生物沖刺港股:年期內虧損超5億 泰格醫藥與北京亦莊是股東

Exploration of mobile application performance tools

Use the API port of the bridge of knowledge and action to provide resources for partners to access

TCP拥塞控制详解 | 2. 背景

几行代码搞定RPC服务注册和发现
随机推荐
电脑自带软件使图片底色变为透明(抠图白底)
TCP拥塞控制详解 | 2. 背景
对接保时捷及3PL EDI案例
宝宝巴士创业板IPO被终止:曾拟募资18亿 唐光宇控制47%股权
Nexus Introduction and Xiaobai use idea Packaging and Upload to Nexus 3 private service detailed tutoriel
【Leetcode】14. 最长公共前缀
IP address translation address segment
A few lines of code to complete RPC service registration and discovery
VMware install win10 image
Chmod command principle and usage details [easy to understand]
Exploration of mobile application performance tools
Ap和F107数据来源及处理
书包网小说多线程爬虫[通俗易懂]
Schoolbag novel multithreaded crawler [easy to understand]
简单线性规划问题
綠竹生物沖刺港股:年期內虧損超5億 泰格醫藥與北京亦莊是股東
Shutter: action feedback
详细介绍scrollIntoView()方法属性
dstat使用[通俗易懂]
Sword finger offer 22 The penultimate node in the linked list