大家好,我是Echa哥。
推薦一個輕量完備的開源前端框架:dagger.js:https://daggerjs.org
什么是 dagger.js
dagger.js 是一個基于 html 的描述式單頁應用開發框架,通過在頁面 DOM 元素上添加語義化的指令來驅動業務邏輯。從語法特性的角度來說,dagger.js 模板 + 指令的工作方式與 Angular/Vue 比較接近。
dagger.js 采用去組件去 api 設計,沒有對第三方代碼或工具的依賴,模型簡單,易于理解。與當前的主流前端框架相比,使用者的整體學習和使用成本更低。
使用 dagger.js,開發者將無須依賴于:
項目構建過程
dagger.js 工作在瀏覽器運行時當中。只需要通過 script 標簽引入框架源碼(release 版本 gzip 壓縮后約 20KB)即可輕松創建單頁應用程序。dagger.js 對項目代碼結構是非侵入式的,您可以以極小成本對歷史項目(即使是非單頁應用程序)進行漸進升級。
包管理工具
dagger.js 內部實現了一個運行時模塊管理器,根據路由配置按需動態加載和解析各類模塊,為您的應用程序進行極限瘦身。
第三方路由管理工具
dagger.js 內置了基于 hash 的路由管理器。開發者無需引入額外的路由管理類庫。
數據狀態管理工具
dagger.js 倡導數據即狀態的技術理念。有別于 React/Vue 等框架單向數據流模型中對于 state/prop 對象的區分,dagger.js 的作用域數據由框架本身進行維護,并具有全域視圖響應性,開發者不必為不同組件間的數據狀態同步而勞心費神。
開發范式
不同于 React Hooks 和 Vue 的組合式 API 方案,dagger.js 提供了更加接近原生 JAVAScript 開發體驗的心智模型。dagger.js 沒有設計任何框架相關的 “語法糖”,開發者編寫的腳本代碼只是普通的原生 JavaScript 函數。函數定義本身是上下文無關的,其觸發時機、調用參數以及副作用完全由調用者(指令)所決定。
dagger.js 中不存在組件(Component)實體的概念,指令是串接作用域數據(Model)和頁面視圖(View)的橋梁。換句話說,在 dagger.js 中,一切業務邏輯都以指令作為調用入口。某些特定指令可以在執行上下文創建作用域數據,而所有指令都可以作為作用域數據的消費者。指令讀取或者修改作用域數據,進而觸發依賴收集或者頁面視圖的響應式更新。
下文中我們將通過示例代碼來體驗 dagger.js 的工作模式。
創建作用域
在 dagger.js 中,我們可以通過生命周期指令 +loading 來創建作用域數據:
+loading 指令在宿主元素(div)初始化時由框架觸發調用。它的副作用是,當表達式的執行結果是一個平凡對象時,框架將依據此對象在當前上下文創建出新的作用域數據。技術上說,這個作用域數據是指令返回平凡對象的代理對象。
作用域數據在宿主元素被銷毀時由框架自動移除,無需開發者手動管理。
指令
在 dagger.js 中,除去生命周期指令之外,還有兩種重要的指令類型:控制指令和事件處理指令。
兩種指令都可以自由讀寫在其聲明位置可見的作用域數據,但是行為有所不同。
控制指令
控制指令在執行過程中會收集參與計算的作用域變量字段,并在指令的依賴項發生變化時動態觸發指令重新執行。我們來看一個例子:
resetnumber" $value#input="a">
span>${ c } = ${ a } + ${ b }
${ d } = 2 * (${ c })
示例鏈接:https://codepen.io/dagger8224/pen/JjpJxzq
上例中,我們在 div 元素上聲明了控制指令 $watch 的兩個實例。其中編號為#1” 的指令依賴于作用域變量下字段 a 和字段 b,編號為#2 的指令依賴于作用域變量下字段 c。當用戶修改 a 或 b 的值時,將首先觸發指令 $watch#1 重新計算,更新字段 c 的值。c 值發生變化后再觸發指令 $watch#2 重新計算,進而更新字段 d 的值。
除去 $watch 指令之外,dagger.js 還提供了更多語義化的控制指令,我們簡單列舉下這些控制指令的使用方法:
$checked 指令用于綁定宿主元素的選中狀態,適用于類型為 radio 和 checkbox 的 input 元素,以及 option 元素。
$class 指令用于將表達式的內容綁定到宿主元素的 class 屬性上。
$each 指令用于循環渲染具有相同視圖模板的數組,對象,或者其他可迭代變量。
$exist 指令用于切換宿主元素及其子級元素的存在狀態。
$html 指令用于在宿主元素下動態創建子級元素。
$file 指令用于綁定用戶選擇的本地文件信息。
1
$selected 指令用于綁定宿主元素的選中值,適用于類型為 radio 和 checkbox 的 input 元素,以及 select 元素。
$style 指令用于綁定宿主元素的 style 屬性。
${ text }
$text 指令用于在宿主元素下動態創建文本內容。大多數情況下,我們也可以使用原地模板字符串(上例第二種方式)來創建動態文本節點,這樣更加簡單靈活。
$value 指令用于將表達式的內容與 input 元素的 value 建立雙向數據綁定。
事件處理指令
與控制指令相比,事件處理指令的用法更加簡單。事件處理指令由用戶操作或系統事件觸發調用,在執行過程中不會對作用域數據進行依賴收集。我們來看一個例子:
alert(message)">click
上例中,button 元素上的 +click 指令聲明了一個鼠標點擊事件處理函數。類似地,您也可以聲明其他的原生事件處理指令(+keyup,+mouseenter 等等),或者自定義事件處理指令(例如:+custom_event)。
接下來我們來看幾個指令的綜合示例:
指令綜合示例 1
下面的示例代碼演示了生命周期指令 +loading,+loaded,+unloading,+unloaded,控制指令 $exist 以及事件處理指令 + click` 的使用:
toggle existThe status of dynamic span: ${ status }Some content
點擊按鈕將切換作用域字段 exist 的值,進而觸發聲明了 $exist 指令的 span 元素加載或移除。
示例鏈接:https://codepen.io/dagger8224/pen/wvmgRyj
指令綜合示例 2
下面的示例代碼演示了控制指令 $each 和 $checked 的使用:
checkbox${ item }
切換復選框的勾選狀態,作用域變量 checked 字段的內容將隨之發生變化,這是雙向數據綁定指令的典型用法。
示例鏈接:https://codepen.io/dagger8224/pen/PoRpROq
各種指令更詳細的定義和使用方法參見官網文檔 。
模塊
接下來我們一起了解下 dagger.js 的模塊設計。
在 dagger.js 中,我們把 html 模板,腳本,層疊樣式表等可復用的代碼片段統稱為模塊。
dagger.js 內部維護了一個運行時模塊管理器,開發者通過 json 格式的配置項注冊模塊,框架將在應用程序首次加載或頁面內路由發生切換時觸發模塊資源按需動態加載、解析和執行。
與作用域數據類似,模塊僅在其注冊層級及子層級生效,避免對全局作用域造成污染。
您可以根據業務需求靈活配置模塊的組合方式(每一個組合方案構成一個名空間)來實現代碼復用。我們來看一個模塊配置項的示例:
上面的配置項中,我們注冊了一個名為 script 的腳本模塊,一個名為 style 的樣式模塊,和一個名為 template 的模板模塊,并將樣式模塊的作用范圍限定為模板模塊內部。
示例鏈接:https://codepen.io/dagger8224/pen/rNJrzzj
路由
作為一個完備的單頁應用開發框架,dagger.js 內置了基于瀏覽器 hash 的路由管理器。當頁面路由發生切換時,根作用域下 $router 對象的內容將同步變化,進而驅動頁面視圖產生響應式更新(需要配合 $html 控制指令使用)。我們來看一個示例:
上例中,當路由從 root 切換至 parent1 之后,頁面內容將發生切換。
示例鏈接:https://codepen.io/dagger8224/pen/zYRQrwP
路由對象的字段內容可以在下面的示例中查看:
示例鏈接:https://codepen.io/dagger8224/pen/PoQBovd
渲染性能
dagger.js 并未采用虛擬 DOM 方案,而是通過細粒度的指令執行來實現頁面視圖增量更新。在 js-framework-benchmark 測試場景中,其綜合運行時性能與 React17 版本相當。
未來計劃
dagger.js 目前已經在多家公司的 B 端管理系統當中得到應用。在未來,我們計劃圍繞框架持續建設周邊生態,通過開源方式對框架進行推廣運營,讓更多的前端開發者有機會了解和使用 dagger.js。
總結
dagger.js 是一個輕量級無依賴的描述式前端開發框架,與主流框架相比,具有更低的學習和使用成本。用戶僅需了解上文中介紹的指令,模塊與路由的相關概念和用法,就可以快速上手使用 dagger.js 構建單頁應用程序。
以上是對 dagger.js 主要功能特性的概要介紹。更多信息請查看官方文檔:https://daggerjs.org
github 地址:https://github.com/dagger8224/dagger.js
更多示例截圖three.js
示例鏈接:https://codepen.io/dagger8224/pen/QWmwaLq
3D Carousel
示例鏈接:https://codepen.io/dagger8224/pen/JjLRbmz
Tesla
示例鏈接:https://codepen.io/dagger8224/pen/RwMGvPv?editors=1010
color picker
示例鏈接:https://codepen.io/dagger8224/pen/vYRmGJp?editors=1010
progress bar
示例鏈接:https://codepen.io/dagger8224/pen/dympJXz?editors=1010
text animation
示例鏈接:https://codepen.io/dagger8224/pen/JjLXppg
您可以在 https://codepen.io/dagger8224/pens 網站查看用 dagger.js 編寫的更多有趣的 demo:
- empty page: https://codepen.io/dagger8224/pen/ZErWBpB
- to do list: https://codepen.io/dagger8224/pen/QWQVYGN
- $scope animation: https://codepen.io/dagger8224/pen/YzeNmRz
- anime.js: https://codepen.io/dagger8224/pen/eYMpzvB
- clock: https://codepen.io/dagger8224/pen/RwMWRYd?editors=1000
- digital clock: https://codepen.io/dagger8224/pen/LYdZEag
- add tags: https://codepen.io/dagger8224/pen/ZErjzwm