实战 | 尝鲜 Svelte 前端框架,开发读书笔记
提到前端開發框架,我相信大家第一時間想到的就是 Vue、React 和 Angular 三大主流。畢竟它們各個都是 GitHub 上 10w+ star 的知名項目,每個前端工程師至少要學習其中一個框架。
但是,最近幾年,一個新的前端框架逐漸出現在人們眼前,它就是后起之秀『 Svelte 』。目前已經接近 4w 個 star,雖然暫時無法撼動三大主流框架的霸主地位,但是其恐怖的 star 增速,值得我們關注和思考。
Svelte 到底是什么樣的框架?
它和三大主流框架有什么不同?
為什么發展如此迅猛?
帶著這些問題,我們一起來學習下 Svelte 框架,并用它從 0 到 1,開發一個讀書筆記小網站。
可以先通過一分鐘的小視頻簡單地了解下 Svelte ~
揭開 Svelte 的神秘面紗
按照官網的描述,Svelte 是一種構建用戶界面的框架,框架自身具有反應性,可以幫助開發者書寫更精簡的代碼,開發出體積更小、更迅速的 App。
使用 Svelte 框架進行開發,需要遵循其特定的語法,編寫 .svelte 后綴的文件。如下是 Svelte 框架的 Hello World 代碼:
你可能會質疑:這不就和 Vue、React 之類的前端框架一樣么?不就是用個數據綁定、抄個 API 和語法風格、改個文件后綴名么?憑什么能獲得 4w 的 star?
其實,近幾年出現的新前端框架并不少,但都被遮擋在了三座大山下,沒有一個能夠像 Svelte 一樣在短期內得到大量的關注。
究竟是什么讓 Svelte 框架破圈突圍,劍指 Angular ?
Svelte 新在哪兒?
我們先來看兩張圖,是對 20 多種前端框架 Demo 項目的性能對比和評測。
第一張圖是對比各框架開發的項目的尺寸:
第二張圖是對比各項目的 Lighthouse 性能評分:
從上面兩張圖,我們發現,Svelte 框架無論是在項目尺寸還是性能方面,都表現卓越。一個用 Svelte 開發的 Demo 項目竟然僅有 15 KB!怎么會這么小呢?有黑魔法?
這和 Svelte 獨特的設計思想有關?;舅袀鹘y的前端框架,在項目運行時都會依賴框架本身的代碼,即引入了框架作為 runtime(運行時),因此需要將框架代碼打進項目包,占用了一定的包大小。
比如 Vue 項目的包管理文件 package.json 中,將 Vue 作為生產環境運行時依賴引入。
"dependencies": {"vue": "^2.6.11" }而 Svelte 框架的核心思想在于『 通過靜態編譯減少框架運行時的代碼量 』(尤雨溪大佬的解釋)。
Svelte 不會將自己打包進項目,而是在編譯打包階段,將 Svelte 組件轉換為原生 DOM 操作。因此,使用 Svelte 開發的項目,并不依賴 runtime,更沒有像 Vue 和 React 中的 Virtual DOM,項目的體積也非常地小。
下面是 Svelte 項目的 package.json 文件,可以發現,svelte 是被作為開發時依賴引入。
"devDependencies": {"svelte": "^3.0.0" }這是 Svelte 和其他前端框架的明顯區別。與其說是 “新”,倒不如說是回歸原始,返璞歸真。
除了不依賴 runtime 和 Virtual DOM 外,Svelte 另一個 “新” 體現在其自身具有反應性,可以輕松地實現狀態管理,而無需像 Vue 和 React 框架一樣引入 Vuex 和 Redux 之類的狀態管理庫。這一點給開發者提供了極大地便利。
了解了 Svelte 框架的獨特之處,讓我們趁熱打鐵,做一個小項目來感受使用 Svelte 進行開發的高效和樂趣~
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-EvEM9s7f-1605794924162)(http://qju0b2x8b.hd-bkt.clouddn.com/u=2751666851,2395317651&fm=15&gp=0.jpg)]
十分鐘開發讀書筆記
接下來,我們要開發一個讀書筆記,來記錄自己每日的學習內容。
先分析下需求,讀書筆記需要有如下基本功能:
成品效果如下:
體驗地址:https://read-note.now.sh/
總共分為四步,順利的話,只用十分鐘就可以開發完成并部署上線~
1. 啟動模板項目
可以通過以下兩種方式下載 Svelte 的模板項目。
方式一
直接下載壓縮包,并手動解壓,地址:https://github.com/sveltejs/template/archive/master.zip
方式二
通過 npx 命令創建一個 Svelte 模板項目:
npx degit sveltejs/template svelte-app下載模板到本地后,進入項目目錄,輸入命令安裝依賴:
npm installSvelte 框架使用 Rollup 作為 JS 模塊打包工具(也是大佬寫的輪子),依賴安裝完成后,通過控制臺輸入命令,在本地啟動項目:
npm run dev控制臺看到如下輸出,項目啟動成功:
瀏覽器訪問 localhost:5000,可以看到如下界面:
2. 開發界面
完成項目模板的下載和啟動后,開始進入讀書筆記界面的開發。
讀書筆記只有一個主頁面,先觀察頁面的布局,分為上下兩部分,上方是一張張相同樣式卡片組成的列表,下方是操作面板:
因此,我們只需要開發兩個組件,卡片 和 操作面板。然后將多張卡片組成列表放在主頁面上方,操作面板固定在主頁面底部。
在項目 src 目錄下新建幾個 .svelte 文件(Svelte 框架的頁面文件,App.svelte 為模板自帶的主頁面),此時目錄結構如下:
.svelte 文件的語法結構和 Vue 框架非常類似,由行為、頁面、樣式三部分組成,分別對應 JavaScript、HTML、CSS 代碼。一個標準的 .svelte 文件代碼如下:
<script>// 編寫網頁交互行為 </script><div><!-- 編寫頁面內容結構 --> </div><style>/* 編寫 CSS 樣式 */ </style>2.1 開發卡片組件
讀書筆記的每張卡片都要有標題、內容和創建日期,還要給卡片編號,并給不同編號的卡片加上不同的顏色。當鼠標移到卡片上時,出現刪除按鈕。
打開 Card.svelte 文件,先在 script 標簽中用 JavaScript 定義幾個屬性變量(組件內唯一)和一個刪除函數:
<script>// 定義變量export let title; // 標題export let content; // 內容export let creationTime; // 創建日期export let index = 0; // 卡片序號// 刪除卡片function doDelete() { } </script>然后編寫卡片的內容,先用一個根 div 標簽括起所有的內容,然后編寫標題、內容、創建時間的 div 標簽。在 Svelte 中,可以直接使用尖括號來輸出變量的值,使用 on:click 指令來綁定鼠標點擊事件:
<div class={`card bg-color-${index % 5}`}><div class="title">{title} <span class="del-btn" on:click={doDelete}>x</span></div><div class="content">{content}</div><div class="creationTime">{creationTime}</div> </div>在 style 標簽中編寫 CSS 代碼,讓卡片變得美美噠:
<style>.card {padding: 1rem;margin: 1rem;color: #fff;border-radius: 0.5rem;}/* 省略... *//* 當鼠標移到卡片上,展示刪除按鈕 */.card:hover .del-btn {opacity: 1;} </style>2.2 開發操作面板組件
操作面板包含兩個輸入框和兩個按鈕,用于添加卡片和導出筆記。
打開 AddCard.svelte 文件,和開發卡片一樣,先編寫 JavaScript,定義幾個屬性變量,以及 “添加” 和 “導出” 函數:
<script>// 在 src 目錄下新建 utils 工具類,編寫獲取當前日期的函數import {getNowDateFormat} from "./utils";// 定義變量let title = ''; // 標題let content = ''; // 內容// 添加卡片function doAdd() { }// 導出筆記function doExport() { } </script>然后編寫操作面板的內容,Svelte 通過 bind:value 指令實現表單數據的雙向綁定:
<div class="add-card"><div class="input-wrapper"><input class="input-title" type="text" placeholder="輸入標題" bind:value={title} /><textarea class="input-content" placeholder="輸入內容" bind:value={content}></textarea></div><button class="add-btn" on:click={doAdd}>添加</button><button class="export-btn" on:click={doExport}>導出</button> </div>最后編寫 CSS 代碼,讓操作面板變得美美噠~ 此處使用 Flex 布局:
<style>/* 操作面板固定在頁面底部 */.add-card {position: fixed;bottom: 0;left: 0;width: 100%;box-sizing: border-box;padding: 1rem;background-image: linear-gradient(135deg, #FEC163 10%, #DE4313 100%);display: flex;}.input-wrapper {flex: 4; /* 使用 Flex 布局 */}/* 省略... */.add-btn, .export-btn {flex: 1;margin-left: 1rem;color: #666;} </style>2.3 將組件放入主頁面
開發完卡片和操作面板組件后,只需要將這些組件丟到 Svelte 模板項目默認生成的主頁面 App.svelte 中,在 script 標簽中通過 import 關鍵字引入組件:
<script>import Card from "./Card.svelte";import AddCard from "./AddCard.svelte"; </script>在 div 標簽中,通過 {# each ... } {/each} 循環語句實現卡片列表,直接通過組件名引入組件:
<div id="app">{#each $cards as card, i}<Card {...card} index={i}/>{/each}<AddCard/> </div>細心的小伙伴可能會好奇,上述代碼第 2 行的 $cards 變量是從哪兒來的呢?不著急,稍后揭曉~
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-WIvEMocd-1605794924170)(http://qju0b2x8b.hd-bkt.clouddn.com/u=1659724492,1719960849&fm=26&gp=0.jpg)]
大功告成!讀書筆記的界面開發好了,但這時,所有的按鈕都沒有任何作用,下面我們來給讀書筆記添加功能。
3. 實現功能
不知道大家有沒有發現,我們要做的讀書筆記,其實就是個簡單的增刪改查項目!
既然是增刪改查,那肯定要有地方存儲數據,記錄數據的變化。通常數據是存在數據庫中的,通過向后端發出請求來操作和查詢數據庫中的數據。
但這里我們只是一個前端項目,沒有數據庫,怎么辦呢?可以直接使用 Svelte 自帶的狀態管理 API 來實現本地數據管理,無需引入任何新的依賴!
3.1 管理卡片數據
在項目 src 目錄下新建 store.js,作為數據管理文件,此時目錄結構如下:
在 store.js 文件中通過 writable 函數定義 cards 可寫變量:
import {writable} from "svelte/store";export const cards = writable([]);定義好之后,cards 已經被 Svelte 框架管理了,可以直接把 cards 當做一個全局變量來使用。
在主頁面中引入 cards,并通過循環語句展示已添加的卡片列表。注意,想要使用狀態變量,要在變量名前添加 $ 符號。此時的主頁面文件 App.svelte 內容如下:
<script>import {cards} from './store'; // 引入 cardsimport Card from "./Card.svelte";import AddCard from "./AddCard.svelte"; </script><div id="app">{#each $cards as card, i}<Card {...card} index={i}/>{/each}<AddCard/> </div>完成了 cards 的展示后,我們依次實現 cards 的添加和刪除吧~
3.2 添加卡片
點擊操作面板的添加按鈕,可以添加卡片。須實現 AddCard.svelte 文件的添加函數:
<script>// 引入狀態import {cards} from './store';import {getNowDateFormat} from "./utils";let title = '';let content = '';function doAdd() {// 校驗if (!title || !content) {alert('標題和內容必須都填!');return;}// 更新卡片狀態,追加一個新卡片cards.update(item => {item = [...item, {title,content,creationTime: getNowDateFormat()}];return item;})} </script>上述文件第 15 行起,通過調用 cards 狀態變量的 update 函數,在原數組后追加一個元素,實現新增卡片。
3.3 刪除卡片
點擊卡片上的刪除按鈕,可以刪除當前卡片。須實現 Card.svelte 文件的刪除函數:
<script>import {cards} from "./store";// 刪除卡片function doDelete() {cards.update(item => {item.splice(index, 1);return item;})} </script>刪除卡片和添加卡片操作類似,都是調用 cards 狀態變量的 update 函數,對原數組進行處理,并使用處理后的數組進行更新。
3.4 導出筆記
點擊操作面板上的導出按鈕,將已添加的卡片導出為 Markdown 格式的筆記文件,實現比較簡單。
首先安裝 file-saver 庫,依賴這個庫實現下載功能:
npm i file-saver實現 AddCard.svelte 文件中的導出函數,將 cards 狀態數組保存為文件:
<script>import {cards} from './store';// 引入 file-saverimport {saveAs} from 'file-saver';// 導出為 read_note.md 文件function doExport() {const texts = [];// 讀取 cards 狀態數組for (const card of $cards) {let text = `### ${card.title}\n${card.content}\n${card.creationTime}\n`;texts.push(text);}// 寫入文件const blob = new Blob(texts, {type: "text/plain;charset=utf-8"});saveAs(blob, "read_note.md");} </script>大功告成!一個精美的讀書筆記就開發完成啦!
3.5 改進
到目前為止,我們只實現了讀書筆記最基本的功能,但這個筆記還存在很多問題:
感興趣地讀者可以試著實現上述改進功能,還可以發揮自己的想象,給讀書筆記添加新功能哦~
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-75Sl3IJD-1605794924173)(http://qju0b2x8b.hd-bkt.clouddn.com/u=1345032634,3216971394&fm=26&gp=0.jpg)]
4. 發布上線
本地開發完成后,怎么將網站發布,讓所有人都能看到呢?
首先通過命令打包項目:
npm run build會在 public 目錄下生成 bundle.js 文件:
此時的 public 目錄結構如下:
怎么發布網站到線上呢?先買臺服務器?
大可不必,可以使用 Vercel。
Vercel 是免費網站托管平臺,可以幫我們部署網站,并生成可訪問的網址。先通過 npm 安裝 Vercel:
npm install -g vercel安裝完成后,進入 public 目錄,通過 vercel 命令發布網站:
cd public vercel deploy --name read-note發布成功,會得到一個網址,打開就能看到精美的讀書筆記網站啦!
在網站中啟用開發者工具(按 F12),能夠看到網頁文件的加載信息,發現整個讀書筆記網站大小才 16 KB!
簡直不講武德啊!
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-uDyOHXgu-1605794924178)(http://qju0b2x8b.hd-bkt.clouddn.com/timg%20(27)].jpg)
億點看法
翻閱了一些論壇,發現大家對于 Svelte 框架的看法褒貶不一。
有的朋友認為 Svelte 為了減少幾十 KB 的體積,而放棄了原本的 runtime 設計和完善的生態,得不償失。畢竟隨著網絡和多媒體的發展,如今一張圖片的大小都要幾百 KB 了,一個頁面可能好幾 MB,還有必要糾結那點大小么?
也有的朋友認為 Svelte 的強大之處正是在于沒有使用 runtime,可以像原生 JS 一樣融合進任何框架和組件,非常適合微前端架構。
我覺得,姑且不論 Svelte 現在的生態怎么樣、有沒有人用,首先作者這種打破思維定式、返璞歸真的勇氣和探索精神值得我們肯定和學習。
脫離業務場景的技術選型都是耍流氓,也許在某些配置較低、網絡較差的小設備中,減小幾十 KB 的包大小真的很有必要!這時,我們可能會摒棄那些重量級的框架,重回原生的懷抱。
Svelte 框架在保證高效極簡開發體驗的同時,保留了原生項目的輕小體積和高性能,這是能夠吸引開發者的爽點。只是目前,Svelte 這種無 Virtual DOM 的設計在生產項目中究竟能發揮多大的優勢、在大型應用中的性能到底如何,還有待觀察,需要更多的打磨和企業的實際檢驗。
相信未來,Svelte 的開發者、建設者和布道者會越來越多,未來可期!
畢竟,多一種技術選型何樂而不為呢?
如果想要進一步學習 Svelte,推薦直接使用官方提供的學習教程,簡潔清晰、容易上手,還能使用在線編輯器進行實時練習和調試。
點擊 鏈接 一鍵傳送至 Svelte 官方學習教程哦~
總結
以上是生活随笔為你收集整理的实战 | 尝鲜 Svelte 前端框架,开发读书笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 程序员须知:必须建立个人知识库,它的重要
- 下一篇: c#操作ecxel的一些资源(downm