<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## 1 mvvm意義 >[info] 以數據雙向綁定為核心,實現UI層與數據層的互動mvvm效果 >[info] mvvm中的m指的是服務器后端的數據層封裝 >[info] mvvm中的v指的是客戶端視圖層的封裝 >[info] mvvm中的vm指的是數據層與視圖層的數據綁定核心 >[info] 正如前面數據綁定介紹mvvm實現了視圖層與數據層的同步刷新 ## 2 思路整理 >[info] mvvm在概念上將視圖層與數據層邏輯分離,ViewModel也就是vm是整個模式的核心,實現Vm需要將模型與視圖關聯起來。總共分為5點 >[info] (1) 實現一個Compiler對元素的每個節點進行指令的掃描和提取。這些指令實現View與Vm的互動 >[info] (2) 實現一個Parser解析元素中的指令,將指令的意圖通過某個刷新函數更新到dom上。比如解析節點<p v-show = "isShow" > </p>后,根據Model中的isShow調用node.style.display控制元素的顯示和隱藏 >[info] (3) 實現一個Watcher注冊Parser對指令解析的刷新函數和對應Model的字段關聯起來 >[info] (4) 實現一個Observer能夠對象所有字段進行set檢測,一旦發生變化可以對所有的消息訂閱者Watcher進行刷新操作 >[info] (5) 通過Observer在Watcher中建立對Model的監聽。當Model在的值發生變化時,監聽者Watcher被觸發刷新,調用步驟2中生成的刷新函數。實現視圖的刷新操作 ## 3 模塊劃分 >[info] 這里將mvvm框架實現為5個模塊。 >[info] (1)編譯模塊Compiler。編譯好指令將指令信息傳遞給解析器Parser處理 >[info] (2)解析模塊Parser。解析指令初始化,生成對應Watcher刷新操作 >[info] (3)訂閱模塊Watcher。管理所有的消息接受與刷新操作的關聯。 >[info] (4)監視模塊Observer。監視數據的變化反饋給Watcher >[info] (5)刷新模塊Update。接受Watcher的刷新消息,進行視圖刷新 ![](https://box.kancloud.cn/2016-05-06_572c4de51a9a8.png) ## 4 編譯模塊Compiler >[info] 編譯模塊實現對視圖中元素的節點指令的掃描和提取。 >[info] 編譯和解析的過程會多次遍歷節點樹,為了提高編譯效率,在mvvm中將節點元素轉換成文檔碎片fragment編譯對象。 >[info]待全部節點編譯完成后將文檔碎片添加回到原來的真實節點中 `vm.complieElement`實現對元素所有節點的掃描和指令提取 ~~~ vm.complieElement = function(fragment,root) { ;獲取孩子節點 var node , childNodes = fragment.childNodes; ;子節點掃描處理 for (var i = 0; i< childNodes.length; i++){ node = childNodes[i]; ;包含指令 if(this.hasDirective(node)){ this.$unCompileNodes.push(node); } ;掃描子節點 if(node.childeNodes.length){ this.compileElement(node,false); } } ; if(root){ this.compileAllNodes(); } } ~~~ `vm.compileAllNode()`實現對`this.$unCompileNodes`中每個節點的的編譯(將指令信息交給解析模塊Parser),編譯完一個節點從緩存隊列刪除,檢`this.$unCompileNodes`直到0。然后將文檔碎片添加到真實節點上 ## 5 解析模塊 Parser >[info] Compiler完成指令的提取,解析模塊Parser對每個指令實現不同的解析方法 >[info] 指令的解析一方面將數據值更新到視圖上, >[info] 指令的解析一方面將刷新函數訂閱到Model的變化監測中 ~~~ ;以v-text指令的解析為例 parser.parseVText = function(node,model){ ;獲取Model中定義的初始值 var text = this.$model[model]; ;更新節點的文本 node.textContent = text; ;或者使用刷新函數 //updater.updateNodeTextContent(node,text); ;在watcher中訂閱model的變化 watcher.watch(model,function(last,old){ node.textContent = last; //刷新函數 //updater.updateNodeTextContent(node,text); }) } ~~~ ## 6 數據訂閱模塊Watcher >[info] Watcher提供watch方法對數據變化進行訂閱, >[info] 一個參數是模型字段model >[info] 另一個是回調函數,實現Observer來觸發的,參數傳入新值last和舊值old。 >[info] Watcher拿到新值后就可以找到model對應的回調進行更新視圖。 >[info] 這里可以知道model和刷新函數是一對多的庴,一個model可以包含多個回調函數(刷新函數)。 ~~~ ;Watcher.watch()方法實現如下 watcher.watch = function(field,callback,context){ var callbacks = this.$watchCallbacks; ;檢查vm.$model中屬性的更新 if(!Object.hasOwnProperty.call(this.$model,field)){ console.warn('The field:'+field+'does not exist in model!'); return; } ;緩存回調函數的數組 if(!callbacks[field]){ callbacks[field] = []; } ;添加回調函數到數組 callbacks[field].push([callback,context]); } ~~~ 數據模型的field字段發生變化時,watcher緩存數組中訂閱field的所有回調 ## 7 數據監聽模塊Observer >[info] Observer是整個mvvm實現的核心基礎。 >[info] 其實現原理與機制見上面兩節。 >[info] 這里使用Object.defineProperty實現對屬性的get/set攔截 ~~~ ;實現object的prop屬性的get和set方法 Object.defineProperty(object,prop,{ get:function(){ return this.getValue(object,prop); } set:function(newValue){ var oldValue = this.getValue(object,prop); if(newValue !== oldValue){ this.setValue(object,newValue,prop); this.triggerChange(prop,newValue,oldValue); } } }) ;實現對數組push和shift的監聽 observer.rewriteArrayMethods = function(array){ var self = this; var arrayProto = Array.prototype; var arrayMethods = Object.create(arrayProto); var methods = 'push|pop|shift|unshift|splice|sort|reverse'.split('|'); methods.forEach(function(method){ Object.defineProperty( arrayMethods, method, function(){ var i = arguments.length; var original = arrayProto[method]; var args = new Array(i); while(i--){ args[i] = arguments[i]; } var result = original.apply(this,args); self.triggerChange(this,method); return result; }); }); array.__proto__ = arrayMethods; } ~~~ ## 8 視圖刷新模塊Updater >[info] 刷新模塊Updater是最簡單,負責每個指令對應的刷新函數。 >[info] 這里接受其他模塊的解析結果。調用Update實現對視圖或者事件的更新 ~~~ ;v-text的刷新函數 updater.updateNodeTextContent = function(node,text){ node.textContent = text; } ;v-bind的刷新函數 updater.updateNodeStyle = function(node,propperty,value){ node.style[propperty] = value; } ~~~ ## 9 雙向綁定實現 >[info] 雙向綁定在數據變化時更新視圖層,或者視圖層變化時數據層也進行同步 >[info] 數據變化更新表單值可以使用Watcher模塊 >[info] 表單變化更新數據只需要監聽表單的事件 ~~~ ;數據到視圖層 watcher.watch(model,function(last,old){ input.value = last; }); ;視圖到數據層 var model = this.$model; input.addEventListener('change',function(){ model[field] = this.value; }); ~~~ ## 10 參考 [mvvm的簡單實現](https://segmentfault.com/a/1190000004847657) [mvvm的完整代碼](https://github.com/tangbc/sugar)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看