無名前端庫
歷經多年,無心插柳,卻編寫了一個直接操作dom的前端庫,簡單易用,類似於react,可以實現react所有功能。rxjs是它唯一的依賴庫。希望能有伯樂賞識,可以合作開源。我為開源做了一點貢獻,我的github是https://github.com/xp44mm
前言
近些年來,前端框架層出不窮,比較著名的有:knockout, angular, react, vue。我還接觸學習過一個比較好的框架叫circle.js。knockout是框架的雛形,比較簡單,容易上手,但是不能無限呼叫,只能做做簡單的頁面。angular我用了,可能沒有找到竅門,半途而廢。但是,卻因此知道另一個庫rxjs,後者的強大是我花了兩年時間才發覺出來的。rxjs這個庫必將千古留名。最後,react庫比較獨特,不使用html模板,直接操作dom,為了函數語言程式設計,又增加了一個虛擬dom用來計算dom那些變化了,那些可以保留。circle.js庫是不斷根據當前狀態,計算出新狀態,然後重新生成介面,計算量太大。不過確實給人啟發,互動式程式設計在前端的應用。
簡介
這個庫直接操作dom生成網頁,不使用html模板。這一點類似於react。這是一個靜態網頁的示例:
h1('Hello, world!')
這個庫與react不同的是,它真正的直接操作dom,沒有使用虛擬dom。以上程式碼就相當於:
let el = document.createElement('h1')
let txt = document.createTextNode('Hello, world!')
el.appendChild(txt)
這個庫直接使用函式進行無限擴充套件。react使用類或函式作為元件,比如
function myWork(){
return div({className:'border'},
welcome(),
byebye(),
)
}
function welcome(){
return div({className:'happy'},'welcome')
}
function byebye(){
return div({className:'enjoy'},'byebye')
}
以上示例都是靜態網頁,還沒有互動,要想互動,可以直接操作dom,也可以使用rxjs進行
這個庫只使用dom規範的子集,許多比較投機取巧的方法和屬性沒有使用。
檢視操作模型必須使用事件,這個事件通過rxjs的fromEvent
進行操作,不推薦使用dom原生的onclick或addenventhandler。
對於常用的窗體控制元件進行了包裝,可以直接使用:
import { BehaviorSubject } from 'rxjs'
import { button, div, textarea, textNode } from '..'
export const textareaTest = () => {
let value = new BehaviorSubject('ddd')
value.subscribe(console.log)
return div(
textarea({ value }),
button('修改').subscribeEvent('click', e => {
value.next('xxxx')
}),
textNode(value)
)
}
執行
需要一個入口的html檔案,這是唯一使用到html的地方。這一點類似於react。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
然後在index.js檔案中有如下入口:
import { fromEvent } from 'rxjs'
fromEvent(document, 'DOMContentLoaded').subscribe(() => {
const root = document.getElementById('root')
root.appendChild(elem)
})
深入
這個庫遵守檢視,模型,業務繫結,三者分離的框架。
模型中的主變數用BehaviorSubject
,從變數用Observable
。
模型操作檢視用訂閱。
Ajax
客戶端與伺服器的通訊是個剛需,這裡使用rxjs庫的fromFetch
直接包裝成Observable
,與上述部分無縫連線。
序列化與反序列化
模型資料,有兩個函式restore和pickout。如果需要儲存核心資料到永久介質,用pickout。如果希望應用介質中的資料用restore。比如:
//載入資料到介面
button({ type: 'button' }, '載入').pipeEvent(
'click',
click$ =>
click$
|> withLatestFrom(textarea$)
|> map(([_, code]) => code)
|> map(code => JSON.parse(code))
|> tap(obj => {
restore(model, obj) // *
})
|> (o => o.subscribe())
//儲存資料
button('儲存').subscribeEvent('click', _ => {
let data = pickout(model) // * model是模型
console.log(data)
})
總結
現在只是描述這個庫如何使用,沒有說明這個庫如何實現。
這多年我一直在家,靠著前幾年的積蓄,一直研究,實現這個庫,總結了好多框架,比如react,深入學習了rxjs,閱讀了好多MDN上的好多規範比如html規範,dom規範,
歷時5年左右,現在將其總結,準備與世人見面。如果大家想讓這個庫早日釋出,希望給我提問題,我更新文章,希望給我點贊,讓有緣人相見。