1. 程式人生 > >vue響應式原理(雙向繫結)-1

vue響應式原理(雙向繫結)-1

首先將該任務分為幾個子任務:

  1. 輸入框以及文字節點與data中的資料繫結
  2. 輸入框內容變化時,data中的資料同步變化。即view=>model的變化
  3. data中的資料變化時,文字節點的內容同步變化。即model=>view的變化。

任務一:資料初始化繫結

瞭解文件片段(DocumentFragment)
DocumentFragment(文件片段)可以看作節點容器,它可以包含多個子節點,當我們將它插入到DOM中時,只有它的子節點會插入目標節點,所以把它看作一組節點的容器。使用DocumentFragment處理節點,速度和效能遠遠優於直接操作DOM。vue編譯時,就是將掛載目標的所有子節點劫持(真的是劫持,通過append方法.DOM中的節點會被自動刪除)到DocumentFragment中,經過一番處理後,再將DocumentFragment整體返回插入掛載目標.

<div id="app">
        <input type="text" v-model="text">
        {{text}}
</div>
<script>
    var vm=new Vue({
        el:"app",
        data:{
            text:"hello world"
        }
    });
    //建立vue物件
    function Vue(options){
        this.data=options.data;
        var id=options.el;
        var dom=nodeToFragment(document.getElementById(id),this);
        document.getElementById(id).appendChild(dom);
    }
    //編譯模板
    function complie(node,vm){
        var reg=/\{\{(.*)\}\}/;
        //節點型別為元素
       if(node.nodeType===1){
           var attr=node.attributes;
           //解析屬性
           for(var i=0;i<attr.length;i++){
               if(attr[i].nodeName==='v-model'){
                   var name=attr[i].nodeValue;
                   node.value=vm.data[name];
                   node.removeAttribute('v-model');
               }
           }
        }
        //節點型別為text
        if(node.nodeType===3){
            if(reg.test(node.nodeValue)){
                var name=RegExp.$1;
                name=name.trim();
                node.nodeValue=vm.data[name];
            }
        }
    }
    //建立文件片段
    function nodeToFragment(node,vm){
        var flag=document.createDocumentFragment();
        var child;
        while(child=node.firstChild){
            complie(child,vm);
            flag.appendChild(child) 
        }
        return flag;  
    }
</script>