Vue中,数据绑定视图的实现原理

示例

比如说,在body中的数据模板是这样的:

<body>
    <div id="root">
        <div>{{message}}</div>
    </div>
</body>

而message的值在数据中是这样表示的:

var data = {
    message: 'hello world'
};

那么在界面中如何让它显示hello world呢?

实现原理讲解

核心原理非常简单,就是使用正则判断文本节点的 {{ }} 的问题。

第一步:

//第一步,获取入口节点,并且创建一个文档碎片。
var $el = document.querySelector('#root');
 //console.log($el);
 var fragment = document.createDocumentFragment();
 fragment.appendChild($el);
 //console.log(fragment);

第二步:

function isTextNode(node) {
    return node.nodeType == 3;
}
function compileElement(fragment) {
    var childNodes = fragment.childNodes;
    [].slice.call(childNodes).forEach(function (node) {

        var text = node.textContent;
        var reg = /\{\{(.*)\}\}/;


        if(node.childNodes && node.childNodes.length){
            compileElement(node)
        } else if(isTextNode(node) && reg.test(text)) {
            //console.log('底层文本解析',RegExp.$1);
            let thisText = data[RegExp.$1];
            node.textContent = thisText;
        }
    });
    //console.log('最终的fragment',fragment)
    return fragment;
}
var mycompile = compileElement(fragment);

第三步:

document.body.appendChild(mycompile);

完整的代码演示示例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>vue指令解析过程</title>
</head>
<body>
    <div id="root">
        <div>{{message}}</div>
    </div>
</body>
<script>
    var data = {
        message: 'hello world'
    };

    //第一步,获取入口节点,并且创建一个文档碎片。
    var $el = document.querySelector('#root');
    //console.log($el);
    var fragment = document.createDocumentFragment();
    fragment.appendChild($el);
    //console.log(fragment);


    //第二步,遍历解析

    function compileElement(fragment) {
        var childNodes = fragment.childNodes;
        [].slice.call(childNodes).forEach(function (node) {

            var text = node.textContent;
            var reg = /\{\{(.*)\}\}/;


            if(node.childNodes && node.childNodes.length){
                compileElement(node)
            } else if(isTextNode(node) && reg.test(text)) {
                console.log('底层文本解析',RegExp.$1);
                let thisText = data[RegExp.$1];
                node.textContent = thisText;
            }
        });
        //console.log('最终的fragment',fragment)
        return fragment;
    }
    var mycompile = compileElement(fragment);
    console.log(mycompile);
    document.body.appendChild(mycompile);


    function isTextNode(node) {
        return node.nodeType == 3;
    }

</script>
</html>

猜你喜欢

转载自blog.csdn.net/mapbar_front/article/details/80494428