久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      淺析vue中complie數(shù)據(jù)雙向綁定原理(代碼詳解)

      之前的文章《一文了解vue中watcher數(shù)據(jù)雙向綁定原理(附代碼)》中,給大家介紹了解了vue中complie數(shù)據(jù)雙向綁定原理。下面本篇文章給大家了解vue中complie數(shù)據(jù)雙向綁定原理,伙伴們過來看看吧。

      淺析vue中complie數(shù)據(jù)雙向綁定原理(代碼詳解)

      vue數(shù)據(jù)雙向綁定原理,和簡單的實現(xiàn),本文將實現(xiàn)mvvm的模板指令解析器

      淺析vue中complie數(shù)據(jù)雙向綁定原理(代碼詳解)

      1)vue數(shù)據(jù)雙向綁定原理-observer

      2)vue數(shù)據(jù)雙向綁定原理-wather

      3)vue數(shù)據(jù)雙向綁定原理-解析器 Complie

      vue數(shù)據(jù)雙向綁定原理,和簡單的實現(xiàn),本文將實現(xiàn)mvvm的模板指令解析器

      上一步實現(xiàn)了簡單數(shù)據(jù)綁定,最后實現(xiàn)解析器,來解析v-model,v-on:click等指令,和{{}}模板數(shù)據(jù)。解析器Compile實現(xiàn)步驟:

      • 解析模板指令,并替換模板數(shù)據(jù),初始化視圖

      • 將模板指令對應的節(jié)點綁定對應的更新函數(shù),初始化相應的訂閱器

      為了解析模板,首先需要獲取到dom元素,然后對含有dom元素上含有指令的節(jié)點進行處理,因此這個環(huán)節(jié)需要對dom操作比較頻繁,所有可以先建一個fragment片段,將需要解析的dom節(jié)點存入fragment片段里再進行處理:

      function node2Fragment(el) {   var fragment = document.createDocumentFragment(),     child;   // 將原生節(jié)點拷貝到fragment   while ((child = el.firstChild)) {     fragment.appendChild(child);   }    return fragment; }

      接下來渲染'{{}}'模板

      //Compile function Compile(el, vm) {   this.$vm = vm;   this.$el = this.isElementNode(el) ? el : document.querySelector(el);   if (this.$el) {     this.$fragment = this.node2Fragment(this.$el);     this.init();     this.$el.appendChild(this.$fragment);   } }  Compile.prototype = {   init: function () {     this.compileElement(this.$fragment);   },    node2Fragment: function (el) {     //...   },    //編譯模板   compileElement: function (el) {     var childNodes = el.childNodes,       self = this;     [].slice.call(childNodes).forEach(function (node) {       var text = node.textContent;       var reg = /{{(.*)}}/; //表達式文本       //按元素節(jié)點方式編譯       if (self.isElementNode(node)) {         self.compile(node);       } else if (self.isTextNode(node) && reg.test(text)) {         self.compileText(node, RegExp.$1);       }       //遍歷編譯子節(jié)點       if (node.childNodes && node.childNodes.length) {         self.compileElement(node);       }     });   },    isElementNode: function (node) {     return node.nodeType == 1;   },    isTextNode: function (node) {     return node.nodeType == 3;   },    compileText: function (node, exp) {     var self = this;     var initText = this.$vm[exp];     this.updateText(node, initText);     new Watcher(this.$vm, exp, function (value) {       self.updateText(node, value);     });   },    updateText: function (node, value) {     node.textContent = typeof value == "undefined" ? "" : value;   }, };

      處理解析指令對相關指令進行函數(shù)綁定。

      Compile.prototype = {    ......   isDirective: function(attr) {     return attr.indexOf('v-') == 0;   },    isEventDirective: function(dir) {     return dir.indexOf('on:') === 0;   },    //處理v-指令   compile: function(node) {      var nodeAttrs = node.attributes,       self = this;     [].slice.call(nodeAttrs).forEach(function(attr) {       // 規(guī)定:指令以 v-xxx 命名       // 如 <span v-text="content"></span> 中指令為 v-text       var attrName = attr.name; // v-text       if (self.isDirective(attrName)) {         var exp = attr.value; // content         var dir = attrName.substring(2); // text         if (self.isEventDirective(dir)) {           // 事件指令, 如 v-on:click           self.compileEvent(node, self.$vm, exp, dir);         } else {           // 普通指令如:v-model, v-html, 當前只處理v-model           self.compileModel(node, self.$vm, exp, dir);         }         //處理完畢要干掉 v-on:, v-model 等元素屬性         node.removeAttribute(attrName)       }     });    },    compileEvent: function(node, vm, exp, dir) {      var eventType = dir.split(':')[1];     var cb = vm.$options.methods && vm.$options.methods[exp];     if (eventType && cb) {       node.addEventListener(eventType, cb.bind(vm), false);     }    },    compileModel: function(node, vm, exp, dir) {      var self = this;     var val = this.$vm[exp];     this.updaterModel(node, val);     new Watcher(this.$vm, exp, function(value) {       self.updaterModel(node, value);     });     node.addEventListener('input', function(e) {       var newValue = e.target.value;       if (val === newValue) {         return;       }       self.$vm[exp] = newValue;       val = newValue;     });    },    updaterModel: function(node, value, oldValue) {     node.value = typeof value == 'undefined' ? '' : value;   },  }

      最后再關聯(lián)起來

      function Vue(options) {   .....   observe(this.data, this);   this.$compile = new Compile(options.el || document.body, this)   return this;  }

      來嘗試下效果

      <!--html--> <div id="app">   <h2>{{name}}</h2>   <input v-model="name" />   <h1>{{name}}</h1>   <button v-on:click="test">click here!</button> </div> <script>   new Vue({     el: "#app",     data: {       name: "chuchur",       age: 29,     },     methods: {       test() {         this.name = "My name is chuchur";       },     },   }); </script>

      OK. 基本完善了

      推薦學習:JavaScript視頻教程

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號