From 4ed81f1f8acb4a5081691b67ef062a9822584904 Mon Sep 17 00:00:00 2001 From: JMRY <376509849@qq.com> Date: Mon, 22 Jan 2024 18:16:38 +0800 Subject: [PATCH] =?UTF-8?q?-=20Version:=201.1.11=20Build=2020240122=20=09-?= =?UTF-8?q?=20=E5=8A=A0=E5=85=A5Model=E5=8F=8C=E5=90=91=E7=BB=91=E5=AE=9A?= =?UTF-8?q?=E7=BB=93=E6=9E=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.react.md | 55 +++++++++++++++++++++++++++++++++++++++++ VERSION.md | 3 +++ react.extensions.dom.js | 39 +++++++++++++++++++++++++++-- 3 files changed, 95 insertions(+), 2 deletions(-) diff --git a/README.react.md b/README.react.md index 0e32d37..ac5f26e 100644 --- a/README.react.md +++ b/README.react.md @@ -1,3 +1,5 @@ + + # DOMHtml for React ## React的插件,使用对象替代JSX来管理React元素。 @@ -165,6 +167,59 @@ //
This is a DIV.
``` +#### 双向绑定 + +- 使用model传递state和onChange的handle函数,从而更加方便地实现双向绑定。 + + - model为数组时,model[0]为value,model[model.length-1]为handle函数,model[1]~model[model.length-1]为扩展数据(如radio的默认选中值)。 + + - model为对象时,将在dom_attr中解构,因此其内部字段与dom_attr保持一致。 + + - 在model中,checkbox的checked属性将被自动映射为model[0]:boolean。 + + - 组件使用model时,需要接收value、onChange两个props。 + + - ```javascript + function ModelRoot(){ + const radioList=[ + `test1`,`test2`,`test3`, + ]; + const [input, setInput]=useState(``); + const [text, setText]=useState(``); + const [check, setCheck]=useState(false); + const [radio, setRadio]=useState(radioList[1]); + + function inputChange(e){ + setInput(e.target.value); + } + function textChange(e){ + setText(e.target.value); + } + function checkChange(e){ + setCheck(e.target.checked); + } + function changeRadio(e){ + setRadio(e.target.value); + } + return rDOM([ + {tag:`input`, model:[input, inputChange]}, + {tag:`textarea`, model:[text, textChange]}, + {tag:`input`, type:`checkbox`, model:[check, checkChange]}, + {tag:`input`, type:`checkbox`, checked:check, onChange:checkChange}, + // 以上两个checkbox项的意义完全一致。 + ...radioList.map((r,i)=>({tag:`input`, type:`radio`, model:[r, r==radio, changeRadio], title:r})), + ...radioList.map((r,i)=>({tag:`input`, type:`radio`, model:{value:r, checked:r==radio, onChange:changeRadio}, title:r})), + ...radioList.map((r,i)=>({tag:`input`, type:`radio`, model:[r, changeRadio], checked:r==radio, title:r})), + ...radioList.map((r,i)=>({tag:`input`, type:`radio`, value:r, onChange:changeRadio, checked:r==radio, title:r})), + // 以上四个radio项的意义完全一致。 + {tag:ModelComponent, model:[input, inputChange]}, + ]); + } + function ModelComponent({value, onChange}){ + // 组件相关代码 + } + ``` + #### CSS样式 - 使用JSX标准的CSS格式。 diff --git a/VERSION.md b/VERSION.md index db94d1e..4f2f3b2 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1,5 +1,8 @@ # JQuery DOM +- Version: 1.1.11 Build 20240122 + - 加入Model双向绑定结构。 + - Version: 1.1.10 Build 20240119 - 修复表格重复输出的bug。 - 修复Invalid prop `attr`警告。 diff --git a/react.extensions.dom.js b/react.extensions.dom.js index c01c5ba..8250de0 100644 --- a/react.extensions.dom.js +++ b/react.extensions.dom.js @@ -46,15 +46,50 @@ function reactDOMHtml(dom_tag,dom_attr,dom_html,dom_html_after){ return dom_attr; // 已被React.createElement封装的情况下,直接返回此对象 } + //Model双向绑定 + if(typeof dom_attr.model==`object`){ + let modelObject={}; + if(dom_attr.model.length!=undefined && dom_attr.model.length>=2 && typeof dom_attr.model[dom_attr.model.length-1]==`function`){ + // model:[value, extend, onChange] + modelObject.value=dom_attr.model[0]; + modelObject.extend=dom_attr.model.slice(1,dom_attr.model.length-1); + modelObject.onChange=dom_attr.model[dom_attr.model.length-1]; + }else{ + modelObject=dom_attr.model; + } + + if(dom_tag==`input` && dom_attr.type!=undefined){ + switch(dom_attr.type){ + case `checkbox`: + dom_attr.checked=modelObject.value; + delete modelObject.value; + break; + case `radio`: + dom_attr.value=modelObject.value; + if(typeof modelObject.extend==`object` && modelObject.extend.length>0){ + dom_attr.checked=modelObject.extend[0]; + delete modelObject.extend; + }else if(modelObject.checked!=undefined){ + dom_attr.checked=modelObject.checked; + delete modelObject.checked; + } + break; + } + } + dom_attr={...dom_attr, ...modelObject}; + } + dom_html=dom_attr.html || dom_html; dom_html_after=dom_attr.htmlAfter || dom_html_after; //对attr进行过滤和改名 let dom_attr_fix_blacklist=[ - `tag`,`html`,`htmlAfter`, + `tag`,`html`,`htmlAfter`,`model`, ] let dom_attr_fix_replace={ - tagName:`tag`, attrName:`attr`, tag_name:`tagName`,attr_name:`attrName`, class:`className`, for:`htmlFor`, + tagName:`tag`, attrName:`attr`, modelName:`model`, + tag_name:`tagName`,attr_name:`attrName`, model_name:`modelName`, + class:`className`, for:`htmlFor`, } let dom_attr_fix={}; for(let key in dom_attr){