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){