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

首頁 > 編程 > JavaScript > 正文

淺析vue數據綁定

2019-11-19 17:54:24
字體:
來源:轉載
供稿:網友

前言:最近團隊需要做一個分享,腳進腦子,不知如何分享。最后想著之前一直想研究一下 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

參考鏈接:

//m.survivalescaperooms.com/article/103297.htm

//m.survivalescaperooms.com/article/99129.htm

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

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 阳西县| 嫩江县| 海原县| 礼泉县| 开远市| 蒲江县| 昌图县| 兴安盟| 三穗县| 新郑市| 连云港市| 佛冈县| 临洮县| 呼玛县| 平邑县| 双城市| 新竹县| 南城县| 古丈县| 双桥区| 方山县| 峨眉山市| 衡山县| 房山区| 高唐县| 体育| 南丰县| 利辛县| 镇平县| 泸州市| 江安县| 黎川县| 库尔勒市| 阿巴嘎旗| 海兴县| 华宁县| 理塘县| 宁武县| 信宜市| 光山县| 桂阳县|