偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

十分鐘帶你入門 Web Components

開發(fā) 前端
Web Components 本身不是一個單獨的規(guī)范,而是由一組 DOM API 和 HTML 規(guī)范所組成,用于創(chuàng)建可復用的自定義名字的 HTML 標簽,并且可以直接在你的 Web 應用中使用。

什么是 web components

組件封裝,是我們前端一直在探討的話題。但現(xiàn)在我們的組件庫,更多的是基于某個框架去實現(xiàn),比如 Vue 的 ElementUI,React 的 ANTD。這種組件的缺點就是對外部框架的依賴,你必須基于 Vue 或者 React 才能使用,假如某一天項目遷移又得重新書寫一套。

那能不能基于原生的 HTML/CSS/JS 就能封裝的組件規(guī)范呢?那就是 Web Components。

Web Components 本身不是一個單獨的規(guī)范,而是由一組 DOM API 和 HTML 規(guī)范所組成,用于創(chuàng)建可復用的自定義名字的 HTML 標簽,并且可以直接在你的 Web 應用中使用。

組件的定義以及核心目標

我認為組件就是內部抽象封裝了一定的邏輯功能,并暴露相關接口給外部調用。

它能夠完成以下的功能:

  • 復用:組件將會作為一種復用單元,被用在多處。
  • 解耦:組件本身隔離了變化,組件開發(fā)者和業(yè)務開發(fā)者可以根據(jù)組件的約定各自獨立開發(fā)和測試。
  • 封裝:組件屏蔽了內部的細節(jié),組件的使用者可以只關心組件的屬性和事件和方法。
  • 抽象:組件通過屬性和事件、方法等基礎設施提供了一種描述??UI?? 的統(tǒng)一模式,降低了使用者學習的心智成本。

那 Web Components 怎么做到以上幾點的呢?

Web Components 的核心概念

主要有以下幾點:

  • Custom elements(自定義元素):一組 JavaScript API,允許您定義 custom elements 及其行為,然后可以在您的用戶界面中按照需要使用它們。
  • Shadow DOM(影子 DOM):一組 JavaScript API,用于將封裝的“影子”DOM 樹附加到元素(與主文檔 DOM 分開呈現(xiàn))并控制其關聯(lián)的功能。通過這種方式,您可以保持元素的功能私有,這樣它們就可以被腳本化和樣式化,而不用擔心與文檔的其他部分發(fā)生沖突。
  • HTML templates(HTML 模板):<template>? 和<slot> 元素使您可以編寫不在呈現(xiàn)頁面中顯示的標記模板。然后它們可以作為自定義元素結構的基礎被多次重用。

我們接下來通過封裝一個 user-card Web Components 組件實戰(zhàn)說明一下。本文 Demo 地址[1]。

HTML 模板

我們先定義好它的 HTML 和 CSS。

<template id="userCardTemplate">
<style>
:host {
display: flex;
align-items: center;
// 省略部分代碼...
}
// 省略很多的CSS 代碼
</style>

<img class="image" />
<div class="container">
<slot name="name"></slot>
<slot name="email"></slot>
<button class="button">Follow Gopal</button>
</div>
</template>

這里留意幾點:

  • template 可以理解成普通的 div,只是這個元素內的所有內容不會直接展示到界面上。
  • template 標簽中可以直接插入 style 標簽在,模板內部定義樣式。其中:host? 偽類用來定義shadow-root 的樣式,也就是包裹這個模板的標簽的樣式。
  • 留意占位符。該占位符可以在后期使用自己的標記語言填充,后面我們會提到。它的使用跟 Vue 的插槽是一樣的。應該說 Vue 借鑒了它的實現(xiàn)。

Custom elements(自定義元素)

使用 CustomElementRegistry.define() 方法注冊您的新自定義元素 ,并向其傳遞要定義的元素名稱、指定元素功能的類、以及可選的其所繼承自的元素。

  • 自定義元素的名稱,一個 DOMString 標準的字符串,為了防止自定義元素的沖突,必須是一個帶短橫線連接的名稱(e.g. custom-tag)。這個也是 Vue 自定義組件命名推薦的使用方式。
  • constructor。自定義元素構造器,包含組件的生命周期的定義。
  • 擴展參數(shù)(可選),該參數(shù)類型為一個對象,且需要包含 extends 屬性,用于指定創(chuàng)建的元素繼承自哪一個內置元素(e.g. { extends: 'p' })。

代碼如下:

class UserCard extends HTMLElement {
constructor() {
// 必須調用 super();
super();
// 創(chuàng)建一個 shadow 節(jié)點,創(chuàng)建的其他元素應附著在該節(jié)點上
var shadow = this.attachShadow({ mode: "closed" });
// 獲取到模板實例
var templateElem = document.getElementById("userCardTemplate");
// 進行拷貝,因為頁面上的模板并不是一次性的,可能其他的組件也要引用
var content = templateElem.content.cloneNode(true);
// this.getAttribute 可以獲取到組件的傳參
content
.querySelector("img")
.setAttribute("src", this.getAttribute("image"));
// 添加到 shadow dom
shadow.appendChild(content);
}
}
// 注冊自定義元素
window.customElements.define("user-card", UserCard);

這里需要留意這個點:

  • Class 類必須調用 super()。
  • 獲取到模板之后,需要通過 clone() 方法進行拷貝,因為頁面上的模板并不是一次性的,可能其他的組件也要引用。
  • this.getAttribute 可以獲取到組件的傳參。

定義好之后,我們就可以直接使用 user-card? 這個自定義元素了,并且可以傳遞屬性給組件,并且能夠通過 slot? 標簽指定 name 屬性,使用上面 HTML 模板中我們定義好的占位符。

<user-card
image="https://p3-passport.byteacctimg.com/img/user-avatar/a0383600d66ccc81b3396b75cf3a95ea~300x300.image"
>
<p slot="name" class="name">Gopal</p>
<p slot="email" class="email">1172597655@qq.com</p>
</user-card>

最終的組件效果如下:

圖片

Shadow DOM

上面的 Demo 中其實已經(jīng)使用了,我們可以在任意一個節(jié)點內部創(chuàng)建一個 Shadow DOM?,在獲取元素實例后,調用 Element.attachShadow()? 方法,就能將一個新的 shadow-root 附加到該元素上。

該方法接受一個對象,且只有一個 mode 屬性,值為 open 或 closed,表示 Shadow DOM 內的節(jié)點是否能被外部獲取。

上面我們設置為 closed。

圖片

假如改成 open,結果如下:

圖片

面臨的挑戰(zhàn)

雖然 Web Components 提出來已經(jīng)很久了,但是普及的程度遠遠沒有 Vue、React 這些框架的組件庫。其主要的問題是,Vue、React 這些框架幫助我們解決了一些視圖渲染的邏輯,比如 React,使用 JSX 和 Css module,我們只需要關心數(shù)據(jù)狀態(tài),不需要像 Web Components 一樣需要更多的關注 HTML 模板,也就帶來了更多的靈活和便利。

總結與思考

精讀《Web Components 的困境》[2]的總結中提到:

Web Components 作為瀏覽器底層特性不應該拿出來和 React,vue 這類應用層框架相比較。Web Components 的方向以及提供的價值都不會跟 應用框架一致。而 Web Components 作為未來的 Web 組件標準,它在任何生態(tài)中都可以運行良好。我倒是更加期待應用層去基于 Web Components 去做更多的實現(xiàn),讓組件超越框架存在,可以在不同技術棧中使用。

確實 React 和 Web Components 也是可以共存的,React 官方文檔也提到:

為了解決不同的問題而生。Web Components 為可復用組件提供了強大的封裝,而 React 則提供了聲明式的解決方案,使 DOM 與數(shù)據(jù)保持同步。兩者旨在互補。作為開發(fā)人員,可以自由選擇在 Web Components 中使用 React,或者在 React 中使用 Web Components,或者兩者共存。

至于應用層去基于 Web Components 去做更多的實現(xiàn),我覺得這是一個很理想的狀態(tài),畢竟要 React、Vue 基于 Web Components 去封裝它們的實現(xiàn),那就需要 Web Components 做更多靈活的規(guī)范和標準,期待這一天的到來吧。

參考

  • 精讀《Web Components 的困境》[3]
  • Web Components MDN[4]
  • Web Components 上手指南[5]

參考資料

[1]Demo 地址: https://codepen.io/gpingfeng/pen/zYRMagp。

[2]精讀《Web Components 的困境》: https://juejin.cn/post/6844903494885851149。

[3]精讀《Web Components 的困境》: https://juejin.cn/post/6844903494885851149。

[4]Web Components MDN: https://developer.mozilla.org/zh-CN/docs/Web/Web_Components。

[5]Web Components 上手指南: https://segmentfault.com/a/1190000039269731。

責任編輯:姜華 來源: 前端雜貨鋪
相關推薦

2020-12-17 06:48:21

SQLkafkaMySQL

2024-11-07 16:09:53

2012-07-10 01:22:32

PythonPython教程

2024-10-25 15:56:20

2024-12-13 15:29:57

SpringSpringBeanJava

2019-04-01 14:59:56

負載均衡服務器網(wǎng)絡

2020-09-27 14:41:37

C語言編程語言計算機

2023-06-07 08:27:10

Docker容器

2020-12-09 16:41:22

LinuxIT開發(fā)

2024-06-19 09:58:29

2021-09-07 09:40:20

Spark大數(shù)據(jù)引擎

2023-04-12 11:18:51

甘特圖前端

2023-08-15 15:50:42

2015-09-06 09:22:24

框架搭建快速高效app

2024-05-13 09:28:43

Flink SQL大數(shù)據(jù)

2023-11-30 10:21:48

虛擬列表虛擬列表工具庫

2019-09-16 09:14:51

2009-10-09 14:45:29

VB程序

2022-08-26 09:01:07

CSSFlex 布局

2023-07-15 18:26:51

LinuxABI
點贊
收藏

51CTO技術棧公眾號