国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > JS > 正文

淺析vue數據綁定

2024-05-06 16:34:38
字體:
來源:轉載
供稿:網友

前言:最近團隊需要做一個分享,腳進腦子,不知如何分享。最后想著之前一直想研究一下 vue 源碼,今天剛好 “借此機會” 研究一下。

網上研究vue數據綁定的文章已經非常多了,但是自己寫一遍,敲一遍demo和看別人的文章是完全不同的,so……搬運工來了

目前數據綁定主要有以下三種實現方式:

1.   臟值檢查(angular.js)    輪詢檢測數據變化

DOM事件,譬如用戶輸入文本,點擊按鈕等。( ng-click )

  • XHR響應事件 ( $http )
  • 瀏覽器Location變更事件 ( $location )
  • Timer事件( $timeout , $interval )
  • 執行 $digest() 或 $apply()

2、Object.defineProperty劫持對象的get、set,從而實現對數據的監控。 (vue)

3、發布/訂閱者模式實現數據與視圖的自動同步

Object.defineProperty的優點

  • “臟值檢測”——數據發生變更后,對于所有的數據和視圖的綁定關系進行一次檢測,識別是否有數據發生了改變,有變化進行處理,可能進一步引發其他數據的改變,所以這個過程可能會循環幾次,一直到不再有數據變化發生后,將變更的數據發送到視圖,更新頁面展現
  • Object.defineProperty() 監控對數據的操作,可以自動觸發數據同步。并且,由于是在不同的數據上觸發同步,可以精確的將變更發送給綁定的視圖,而不是對所有的數據都執行一次檢測。

Object.defineProperty的用法

var a = {};?Object.defineProperty(a, "b", {?  set: function (newValue) {?  console.log("我被賦值了!" + newValue);?  },?  get: function () {?  console.log("我被取值了!");?  return 2  }?})?a.b = 3; //我被賦值了!?console.log(a.b); //我被取值了! //打印 2

由上面的例子看出,Object.defineProperty  傳人3個參數

第一個: a對象

第二個: a對象里面的b屬性

第三個: 屬性比較多,列舉有用的 value,set,get,configurable

數據綁定原理:

1、實現一個數據監聽器Observer,對數據對象的所有屬性進行監聽,如有變動則拿到最新值并通知 dep數組

2、實現一個指令解析器Compile,對每個元素節點的指令進行掃描和解析,根據指令模板替換數據

3、實現一個dep數組 ,能夠訂閱并收到每個屬性變動的通知,執行指令綁定的相應回調函數,更新視圖

1. 實現observer

var data = {name: 'beidan'};?observe(data);?data.name = 'test'; // 監聽到值變化了 beidan 變成 test??function observe(data) {?  if (!data || typeof data !== 'object') {?  return;?  }?  // 取出所有屬性遍歷?  Object.keys(data).forEach(function(key) {?   defineReactive(data, key, data[key]);? });}
function defineReactive(data, key, val) {?? Object.defineProperty(data, key, {? enumerable: true, // 可枚舉?   configurable: false, // 不能再define  get: function() {?     return val;?   },?   set: function(newVal) {?     console.log('監聽到值變化了 ', val, ' 變成 ', newVal);?   val = newVal;?   }?  });}

2. 維護一個數組

function Dep() {?  this.subs = [];}?Dep.prototype = {?  addSub: function (sub) {?  this.subs.push(sub);?  },?  notify: function (val) {?   this.subs.forEach(function (sub) {?    sub.update(val)?  });? }?};function defineReactive(data, key, val) { Object.defineProperty(data, key, { …… set: function(newVal) {  if (val === newVal) return;  console.log('監聽到值變化了 ', val, ' 變成 ', newVal);  val = newVal;  dep.notify(val); // 通知所有訂閱者  }  });}

3. compile

bindText: function () {?  var textDOMs = this.el.querySelectorAll('[v-text]'),?bindText,_context = this;??  for (var i = 0; i < textDOMs.length; i++) {?   bindText = textDOMs[i].getAttribute('v-text'); textDOMs[i].innerHTML = this.data[bindText];? var val = textDOMs[i]??  var up = function (text) {?    val.innerText = text?  }? _context.dep.addSub({?    value: textDOMs[i],?    update: up?  });?  }?},

最后,附上源碼 github   https://github.com/beidan/vue_bind

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持VeVb武林網!


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 额敏县| 高青县| 彝良县| 邓州市| 新竹市| 湛江市| 屏山县| 尼勒克县| 定襄县| 吉木乃县| 老河口市| 景德镇市| 固原市| 镇安县| 余庆县| 安顺市| 买车| 舞钢市| 林西县| 大方县| 西贡区| 桐城市| 从化市| 镶黄旗| 灵璧县| 洮南市| 垦利县| 喀喇沁旗| 济南市| 冀州市| 隆林| 象州县| 延边| 延川县| 襄樊市| 屯留县| 开封县| 江陵县| 博乐市| 宜兰县| 张掖市|