使用 Svelte 來構建 Web Component (超簡單方便)
每個開發人員都應該關注程式碼中的可重用性以及程式碼的業務隔離,這樣可以讓業務邏輯與應用架構分離,提升系統的擴充套件性。而 Web Component 就是這樣一個技術,可以讓我們建立一個獨立的可重用元件。
本文將介紹使用 Svelte 建立通用的 Web Component 的完成過程。『通用』指的是該元件不侷限於 Svelte 應用,還可以用於任何 JavaScript 應用程式(如 Vue、React 等),同時還將介紹使用 Svelte 建立 Web Component 的一些侷限性。
什麼是 Web Component?
Web Component 可以讓我們建立可重用的、自定義的封裝了樣式以及功能的 HTML 元素。
例如,我們使用如下程式碼來建立一個導航條:
<style> /* CSS code for our navbar */ </style> <navbar> <!-- Some long code for our navbar --> </navbar>
如果用 Web Component 技術,我們可以定義一個自定義元素(如 <custom-navbar/>),然後你可以在網頁任一地方使用該元素顯示導航條,同時這個導航條的樣式和頁面其他元素的樣式是完全隔離的,不會相互影響。而這項技術被稱之為 Shadow DOM (影子 DOM)。
什麼是 Shadow DOM?
Shadow DOM 是一個較小的、獨立的 DOM,它與主 DOM 分開渲染,允許我們將樣式和標記行為隔離到單個元件中。Shadow DOM 本質上允許我們將元件功能進行封裝和隔離,我們可以單獨對其設定樣式、編寫功能指令碼,而不會干擾應用程式的其餘元素。
你大概對 Web Component 有一個基本的認識,下面我們開始用 Svelte 來編寫一個簡單的元件。
構建 Web Component
準備工作
為了完成本文剩餘的內容學習,需要你對掌握以下知識:
- 對 HTML, CSS 和 JavaScript 有基本的認識
- 熟悉命令列操作環境
- 需要一個文字編輯器
- 最好對 Svelte 有一些基本的瞭解(可以看看我之前翻譯的文章 https://my.oschina.net/javayou/blog/5309554 )
開始
本文我們將開發兩個元件:
- 第一個元件是一個卡片元件,接收三個屬性分別是:卡片標題、卡片描述以及圖片,該元件名為
<my-card />
- 第二個元件是一個帶樣式的按鈕,接收一個
type
的屬性,通過該屬性來確定按鈕的顯示樣式,元件名稱為<cool-button />
同時我們將使用兩種元件的釋出方式,一個是打包到單一檔案,另外一個是每個元件釋出到一個獨立的檔案中。
下圖顯示的是兩個元件執行後的外觀:
我們從建立一個 Svelte 應用開始,並安裝必須的包:
npx degit sveltejs/template web-component-tut cd web-component-tut npm install
上述命令執行完畢就可以使用如下命令啟動一個測試環境:
npm run dev
然後我們開啟瀏覽器訪問 http://localhost:8080 就可以看到一個最基礎的 Svelte 應用執行起來後的樣子:
開發一個元件
使用 Svelte 生成通用 Web Component 的過程類似於建立常規 Svelte 元件的過程,只是進行了一些修改。
為了建立第一個卡片元件,我們首先建立一個檔案 src/Card.svelte
並定義元件的屬性、樣式以及 HTML 標籤,程式碼如下:
<script> // component props // Camel case not supported for props, see drawback section. export let card_title, card_desc, card_img; </script> <main> <div class="card-container"> <div class="card"> <img src={card_img} alt="My product" /> <div class="card-body"> <div class="row"> <div class="card-title"> <h2>{card_title}</h2> </div> </div> <p> {card_desc} </p> <button>Do Something</button> </div> </div> </div> </main> <style> .card { max-width: 350px; border-radius: 5px; box-shadow: 0 4px 6px 0 #00000033; padding: 0 0 10px 0; } .card img { width: 100%; height: auto; } .card-body { padding: 5px 10px; } .card-body p { color: #575757; margin-bottom: 20px; font-size: 14px; } </style>
你可以在其他元件中使用這個卡片元件,如下所示(這一步可忽略):
<script> import Card from "./Card.svelte"; </script> <main> <Card card_title="My Card Title" card_desc="Lorem ipsum dolor…" card_img="path/to/my-image.png" /> </main>
接下來是按鈕元件,檔名 /src/Button.svelte
程式碼如下:
<script> // Component props export let type = "solid"; </script> <button class={type == "solid" ? "btn-solid" : "btn-outline"}> <slot /> </button> <style> button { padding: 10px; color: #fff; font-size: 17px; border-radius: 5px; border: 1px solid #ccc; cursor: pointer; } .btn-solid { background: #20c997; border-color: #4cae4c; } .btn-outline { color: #20c997; background: transparent; border-color: #20c997; } </style>
該元件的使用方法如下(可忽略):
import Button from "./Button.svelte"; <Button type="outline">Click me</Button>
將自定義元件轉成通用元件
我們需要將自定義 Svelte 元件轉成通用的 Web Component ,這樣才可以在其他框架中直接使用。
要做這個轉換操作,我們需要在 Svelte 配置檔案中設定讓編譯器生成自定義元素。開啟 rollup.config.js
在 plugins 增加一個 compilerOptions
配置項,在該配置項下增加 customElement: true 配置資訊,如下所示:
... plugins: [ svelte({ compilerOptions: { dev: !production, customElement: true, ...
然後我們需要給兩個元件分別定義一個元素名稱,開啟 Card.svelte
檔案,在檔案開頭第一行插入如下內容:
<svelte:options tag="my-card" />
上述 tag
屬性值代表元件的標籤名稱。
同樣的,開啟 Button.svelte 給第二個元件指定一個標籤名稱:
<svelte:options tag="cool-button" />
最後一步是在 main.js
中引入這兩個元件,開啟 /src/main.js
將裡面的內容替換成如下兩行:
import Button from "./Button.svelte"; import Card from "./Card.svelte";
這裡我們已經完成了兩個元件的開發步驟,下一步就是打包元件以便其他的應用可以使用這兩個元件,開啟命令列視窗進入專案所在目錄執行如下命令:
npm run build
該命令將生成兩個檔案,分別是 build.js
和 build.map.js
, 檔案位於專案下的 /build
目錄。其中build.js
是打包的兩個元件,而 build.map.js
是 build.js
原始碼對映檔案。
如果上述步驟順利完成,我們就可以將 bundle.js
拷貝到一個新目錄,然後建立一個 index.html
檔案,內容如下:
<!DOCTYPE html> <html> <head> <title>My website</title> <script src="./build.js"></script> </head> <body> <div class="container"> <div class="row"> <div class="col"> <my-card card_title="Red Person" card_desc=" Lorem ipsum dolor sit, amet consectetur.." card_img="https://bit.ly/34B3zHX" > </my-card> <!-- Image credit - Shubham Dhage on unsplash.com --> </div> <div class="col"> <div class="border-bottom py-5"> <cool-button> Solid Cool Button </cool-button> <cool-button type="outline"> Outlined Cool Button </cool-button> </div> </div> </div> </div> </body> </html>
這是一個再簡單不過的 HTML 頁面了,該頁面使用了上述兩個元件,在瀏覽器中顯示為如下效果:
元件分割
在某些情況下我們不需要將多個元件打包到同一個 js 檔案中,我們希望每個元件有一個獨立的 js 檔案。要實現這個場景只需在 rollup.config.js
的 input 和 output 中進行配置即可。
在 input 的配置中我們可以指定一個數組,陣列的元素就是每個元件的檔案路徑,而 output 指定為輸出的目錄即可:
export default { input: ["src/Card.svelte", "./src/Button.svelte"], output: { format: "iife", dir: "public/build/", }, ...
修改完成後再次執行 npm run build
,我們就可以在 build 目錄中看到兩個檔案 Button.js
和 Card.js
。
使用方法類似:
<script src="Button.js" type="module"></script> <cool-button type="outline">Click Me</cool-button> <!-- another-page.html --> <script src="Card.js" type="module"></script> <my-card card_title="..."></my-card>
主要缺點
到這裡我們已經掌握了使用 Svelte 開發 Web Component 的方法,這個過程非常之簡單,但是,使用 Svelte 開發 Web 元件會有一些缺點如下:
- 元件的屬性名稱不允許使用駝峰命名法,例如你會發現使用形如 cardTitle 這樣的屬性名就無法正常工作,而駝峰命名法又是 JavaScript 推薦的命名風格。這是一個 Bug,不過如果你使用的是 Vite ,那麼有一個 workaround plugin 可以解決這個問題。
- 如果不標記Web元件,就無法在Svelte中重用它們 - 不幸的是,您還必須標記要在自定義Web元件中使用的每個Svelte元件
加入你有一個Header.svelte
檔案需要作為<my-header />
元件輸出,但同時這個元件又依賴另外一個Nav.svelte
檔案,而 Nav.svelte 我們不希望作為 Web 元件輸出,這個問題使得我們必須將 Nav.svelte 也作為元件輸出,否則程式就會報錯。好在這個問題現在也有解了(詳情請看 這裡),我們可以通過配置來解決這個問題,雖然看起來不是那麼的爽,就這樣吧,又不是不能用。 - 瀏覽器的支援問題 — JavaScript
customElement
API 就是用來建立 Web Component 的底層 API,該 API 目前並沒有被所有的瀏覽器支援,我們需要引入 Polyfill 來解決這個檔案,詳情請看 webcomponents official 。
總結
在本文中,我們學習瞭如何使用 Svelte 建立通用卡片和按鈕元件,生成捆綁檔案,拆分它們,甚至在單獨的 HTML 頁面中重用此元件。
動手試試吧?
- 使用 Svelte 來構建 Web Component (超簡單方便)
- 解決 Error: Cannot find module '../5/CheckObjectCoercible' 問題
- 當碼農不如種紅薯?
- 前端環境管理2大利器nvm和nrm
- Svelte Native 與 React Native 的比較
- 與自我相處,解鎖居家生活的精彩「另一面」
- 在 Gitee 上儲存你的 IntelliJ IDEA 設定資訊
- Svelte 元件之間通訊的 6 種方法
- Go語言搬磚 dolphinscheduler任務處理
- Go語言搬磚 kylin任務自動化
- 在 Windows 上執行 OpenSearch(ElasticSearch)
- 前端框架 React 和 Svelte 的基礎比較
- k8s series 24: calico初級(監控)
- 一鍵建立k8s使用者並授於檢視pod日誌許可權
- maxwell採集binlog傳送kafka(docker方式安裝)
- 一個漂亮的linux系統資源監控小工具,讓你輕鬆定位CPU高,記憶體高的程序
- hadoop熱刪除datanode(命令列方式版本)
- elasticsearch7.x滾動擴縮容-停機維護(不影響業務)
- kafka消費組延遲小工具
- 陌陌推出“樹莓”APP入局種草賽道,如何避免碰瓷“小紅薯”?