编程技术文章分享与教程

网站首页 > 技术文章 正文

无名前端库 无名前端库是什么

hmc789 2024-11-14 16:37:35 技术文章 2 ℃

# 无名前端库

历经多年,无心插柳,却编写了一个直接操作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库是不断根据当前状态,计算出新状态,然后重新生成界面,计算量太大。不过确实给人启发,交互式编程在前端的应用。对于我来说,目前最好的前端库是react,这个库也是类似于react操作dom。

## 简介

这个库直接操作dom生成网页,不使用html模板。这一点类似于react。这是一个静态网页的示例:

```js

h1('Hello, world!')

```

这很好理解,翻译成html

```html

<h1>Hello, world!</h1>

```

所有元素设计成如下格式:

```js

tag({...props},...children)

```

这个库与react不同的是,它真正的直接操作dom,没有使用虚拟dom。以上代码就相当于:

```js

let el = document.createElement('h1')

let txt = document.createTextNode('Hello, world!')

el.appendChild(txt)

```

这个库直接使用函数进行无限扩展。react使用类或函数作为组件,比如

```js

function myWork(){

return div({className:'border'},

welcome(),

byebye(),

)

}

function welcome(){

return div({className:'happy'},'welcome')

}

function byebye(){

return div({className:'enjoy'},'byebye')

}

```

以上示例都是静态网页,静态网页没有太大用处,要想更有用,必须使其动起来。

## 绑定属性

如上所述,属性可以赋值常量,也可以和一个Observable关联,界面随着Observable的内容,自动更新。

```js

export const checkboxTest = () => {

let checked = new BehaviorSubject(false)

return div(

checkbox({ checked }),

textNode(checked)

)

}

```

上述代码,文本节点,随着Observable的变化,自动更新界面。注意,BehaviorSubject是可以主动施加变化的Observable。checkbox是窗体控件,绑定了事件。

## 绑定事件

几乎所有常用事件都已经封装,如上,只需要将一个可以施加变化的BehaviorSubject对象放置到checked位置,这个事件就绑定了。

这个库只使用dom规范的子集,许多比较投机取巧的方法和属性没有使用。

视图操作模型必须使用事件,这个事件通过rxjs的`fromEvent`进行操作,不推荐使用dom原生的onclick或addenventhandler。

对于常用的窗体控件进行了包装,可以直接使用:

```js

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。

```js

<!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文件中有如下入口:

```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。比如:

```js

//加载数据到界面

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年左右,现在将其总结,准备与世人见面。如果大家想让这个库早日发布,希望给我提问题,我更新文章,希望给我点赞,让有缘人相见。

Tags:

标签列表
最新留言