吃饱撑的系列-React的jsx改为domString支持

用domString改造React的JSX

看了几天React,总觉得别扭,jsx看起来美好,但是对熟悉html的人来说,各种别扭,加之这些天对es6的了解加深,觉得es6的模板字符串配合domString其实也并不差。
学习React的前几篇,就提到JSX的解析不要在生产环境下使用babel.js
看来jsx非要用node.js本地先编译啥的。
用react就是为了个简单的绑定,结果用了工具,还要用工具的工具来使用工具,nnd,及其不爽。

正好吃饱撑的消化消化,想在js环境下,直接用domString替换JSX。以便以后简单利用react,直接引用react.js无需再烦jsx的问题。

替换jsx有两种思路。
思路1:直接将domString转换为React使用的虚拟dom,再传递给ReactDOM.render进行渲染。
思路2:将domString用React的函数转换为虚拟dom。

第一种思路有点问题在于,就算我完全破解了虚拟dom的内容,react一改,就完全不能用了。

第二种思路相对就简单了,根据babel转换出来的js代码,写个函数,用react的函数,转虚拟dom,react只要不是大变化,理论上是该保持兼容的。
决定使用第二种思路:直接上代码
先来个将domString转换为dom的函数

    function getDom(domString){
        let mainDom = document.createElement("div")
        mainDom.innerHTML = domString
        return mainDom.firstChild
    }

再将dom通过react的函数转换为虚拟dom,为啥先转为dom呢,主要式懒,js操作dom的函数多。O(∩_∩)O

    function getReactDom(domNode,idx=0){
        if (typeof(domNode) === 'string'){domNode = getDom(domNode)};
        let domChild = [];
        // 不加个key,react运行时候会报警告。我就是把虚拟dom和用babel转出来的虚拟dom一模一样都没用。
        let domAttrs = {key:idx};
        // 属性patch,class-> className
        if (domNode.attributes && domNode.attributes.length){
            for (let attr of domNode.attributes) {
                let n={};
                let newName = (attr.name === "class") ? "className" : attr.name;
                n[newName]=attr.value;
                domAttrs = {...domAttrs,...n};
            };
        };
        // 只处理nodeType是1,3的节点。1是Element,3是TextNode,8是html注释(jsx有html注释会报错,这里直接忽略)
        if (domNode.childNodes.length){
            for (let dC of domNode.childNodes) {
                switch(dC.nodeType){
                    case 1:
                        idx ++;
                        domChild.push(getReactDom(dC,idx));                        
                        break;
                    case 3:
                        if(dC.nodeValue.trim()) domChild.push(dC.nodeValue);
                        break;
                };    
            };
        };
        if (domChild.length ===1){domChild = domChild[0]}
        return React.createElement(domNode.tagName.toLowerCase(),domAttrs,domChild)
    };

写个简单的react函数

    function Rsrvn(props){
        let vDom;
        switch (props.rslt){
            case "succ":
                vDom = getReactDom(getDom(`<div id="ab" class="col-xs-10 col-sm-8 col-xs-offset-1 col-sm-offset-2">
                            f3 <span>f4</span> success<!--  文档注释部分 -->
                        </div>`));
                break;
            case "fail":
                vDom = getReactDom(getDom(`<div id="ab" class="col-xs-10 col-sm-8 col-xs-offset-1 col-sm-offset-2">
                            f5 <span>f6</span> fail
                        </div>`));
                break;
            default:
                vDom = getReactDom(getDom(`<div id="ab" class="col-xs-10 col-sm-8 col-xs-offset-1 col-sm-offset-2">
                            请填写相关信息!
                        </div>`));
        }
        return vDom
    };

弄个数据随便测试一下:

myrslt = {rslt:"succ"};
let element = Rsrvn(myrslt);
ReactDOM.render(
    element,document.getElementById("aabb")
    );

看着全部都是函数写法的react,顺眼多了。

嗯,开篇我就说了,这个纯粹吃饱撑了,不接受批评。嗯觉得我代码还能优化优化,更简洁,更有效率,可以说一说。

最后:版权声明
版权所有,转载、使用代码均可,但需留本文地址供有想法的同志溯源讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值