# twin-node **Repository Path**: zhang_xiangm/twin-node ## Basic Information - **Project Name**: twin-node - **Description**: TwinNode是一个轻量级html文档构建库,提供声明式构建和扁平化配置两大核心功能。无虚拟DOM,零成本抽象,专注于高性能场景。 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-08-10 - **Last Updated**: 2025-08-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # twin-node.js ## 简介 TwinNode是一个轻量级html文档构建库,提供声明式构建和扁平化配置两大核心功能。无虚拟DOM,专注于高性能场景。 ## 安装 ```console npm i twin-node ``` ## 快速上手 ```javascript //第一步:导入 import "twin-node" //或 //第二步:用以下标准语法解构出标签函数 const {table,thead,tbody,tr,th,td} = $$.tags //第三步:声明式构建文档 const node = table( thead( tr( th("学号"),th("姓名"),th("性别") ) ), tbody( tr( td(1),td("张向明"),td("男"), ), tr( td(2),td("蒋海艳"),td("女"), ) ) ) //第四步:挂载 const body = $$.q("body") node.appendTo(body) ``` ## 帮助文档 ### 1. 概念 #### 1.1 孪生节点 孪生节点是在Node实例(以下统一称为真节点)上构建的一层代理,其实现原理是一个Proxy。孪生节点的目的是为了使用精简指令集来操作真节点的对象属性、标签属性、样式、事件,并提供链式写法。请看如下示例: ```javascript TwinNode("div") //创建了一个div真节点,并返回其孪生节点 .attr("id","div1") //配置attribute .class("my-div") //配置class .css("color","red") //配置样式 .on("click",event=>console.log(event)) //配置事件 ._title("标题") //更精简的配置attribute .backgroundColor("green") //更精简的配置样式 .Mousedown(event=>console.log(event)) //更精简的配置事件 ``` #### 1.2 TwinNode函数 TwinNode是一个用来构建孪生节点的函数,其简写形式为$$,以下全部用简写形式。此外TwinNode有一个使用非常频繁的静态方法TwinNode.q(selector),其作用是在document下搜索DOM节点,并包装为孪生节点。 ``` javascript let t1 = $$("div") //创建了一个div真节点,并返回其孪生节点 let t2 = $$(document.querySelector("div")) //将已经存在的真节点包装为孪生节点 let t3 = $$.q("div") //等效于$$(document.querySelector("div")) ``` #### 1.3 标签函数 标签函数是用来声明式构建孪生节点的函数,可以使用以下两种方式来获得标签函数: ```javascript //1: 通过对象解构语法获得,要求标签函数名与要构建的DOM节点标签名完全一致 const {div,span} = $$.tags //2: 通过TwinNode.defineTag获取,可自定义函数名 const myDiv = $$.defineTag("div") ``` 声明式构建孪生节点示例 ```javascript const {table,tr,td} = $$.tags let twinNode = table( tr( td("单元格11"), td("单元格12"), ), tr( td("单元格21"), td("单元格22"), ) ) ``` #### 1.4 解孪生 解孪生是指从孪生节点上获取其真节点的过程,通过孪生节点的下标0就可以完成解孪生 ```javascript const div = $$.tags.div //创建标签函数 const twinNode = div("内容") //创建孪生节点 const realNode = twinNode[0] //解孪生 ``` #### 1.5 无参组件 所谓组件就是一个能够返回孪生节点或真节点的函数,以下是创建组件和复用组件的过程 ```javascript //定义函数既是创建组件 function component() { return tbody( tr( td("内容"), td("内容"), td("内容") ), tr( td("内容"), td("内容"), td("内容") ) ) } //在构建复杂节点时复用组件 const node = table( thead( tr( th("字段1"), th("字段2"), th("字段3") ) ), component //等价与component(),框架会自动调用无参的函数组件 ) //挂载节点 const body = $$.q("body") node.appendTo(body) ``` #### 1.6 有参组件 无论是无参组件还是有参组件,其本质都是一个能返回孪生节点或真节点的函数,唯一的不同点是有参的组件在使用时必须手动传参调用。示例如下: ```javascript //定义组件 function component(data) { return tbody( data.map(item => tr( td(item.id), td(item.name), td(item.sex === 1 ? "男" : "女") ) ) ) } //准备数据 const myFamily = [ { id: 1, name: "张向明", sex: 1 }, { id: 2, name: "蒋海艳", sex: 2 }, { id: 3, name: "张泽珩", sex: 1 } ] //使用组件 const node = table( thead( tr( th("字段1"), th("字段2"), th("字段3") ) ), component(myFamily) //调用组件函数并传入参数 ) //挂载节点 const body = $$.q("body") node.appendTo(body) ``` #### 1.7 文档碎片 下滑线_是一个特殊的标签函数,其用途是创建一个文档碎片孪生节点,其真节点是一个DocumentFragment实例。使用方式如下: ```javascript //创建文档碎片组件 function component() { const {_} = $$.tags //解构出_函数 return _( li("项目1"), li("项目2"), li("项目3") ) } //复用组件 const node = ul( component ) //挂载节点 const body = $$.q("body") node.appendTo(body) ``` ### 2. 标签函数参数详解 标签函数接收多个不同类型的参数,每种类型的参数,在构建过程中都有自己特定的含义,这些参数的表义与顺序无关,但文档结构与顺序有关。标签函数可无限嵌套调用,以实现复杂的文档构建。请看如下示例: ```javascript const node = ul( //以下空值将被忽略,不参与构建 null,undefined,"", //如果参数是一个孪生节点,则会将其真节点追加到ul中 li("项目1"), li("项目2"), //如果参数是一个数组,将被自动展开,并追加到ul中 [li("项目3"),li("项目4")], //如参数是一个函数,将会自动运行并将结果递归追加到当前节点 ()=>li("项目5"), //如果参数是一个正则表达式,则用来为ul配置id和class和其他属性 //#开始的片段将被解析成id,多个id取最后一个 //.开始的片段将被解析成className,多个className可叠加 //[]中的片段将被解析成attribute,特别注意中括号中的中划线一定要转义成\- //此处唯一的目的是让问题变简单,如果是复杂的attribute(如style)推荐用object语法 /#ul5.class1.class2[attribute1][attribute2=2][attribute\3=3]/, //如果参数是一个object,则用来配置ul的attribute、样式、事件 { title: "标题", style: { color: "red", fontSize: "20px" }, click: event => console.log(event.target) }, //如果参数是一个已经存在的