无名前端库
- 2020 年 8 月 27 日
- 筆記
- javascript
无名前端库
历经多年,无心插柳,却编写了一个直接操作dom的前端库,简单易用,类似于react,可以实现react所有功能。rxjs是它唯一的依赖库。希望能有伯乐赏识,可以合作开源。我为开源做了一点贡献,我的github是//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年左右,现在将其总结,准备与世人见面。如果大家想让这个库早日发布,希望给我提问题,我更新文章,希望给我点赞,让有缘人相见。