Vue數(shù)據(jù)響應(yīng)原理

Vue 數(shù)據(jù)響應(yīng)依賴于Object.defineProperty,這也是Vue不支持IE8的原因道媚。Vue通過設(shè)定對(duì)象屬性的setter/getter方法來監(jiān)聽數(shù)據(jù)的變化言蛇。通過getter進(jìn)行依賴收集,而每個(gè)setter方法就是一個(gè)觀察者福青,在數(shù)據(jù)變更的時(shí)候通知訂閱者更新視圖。


看看簡單的雙向綁定實(shí)現(xiàn)

const obj = {

object.defineProperty(obj, 'hello', {
  get(value) {
    console.log('use get')
  },
  set(newVal, oldVal) {
    console.log('user')
  }

<input type="text" id="a"/>
<span id="b"></span>

<script>
    const obj = {};
    Object.defineProperty(obj,'hello',{
      get(){
        console.log("啦啦啦,方法被調(diào)用了");
      },
      set(newVal){
        document.getElementById('a').value = newVal;
        document.getElementById('b').innerHTML = newVal;
      }
    })
    document.addEventListener('keyup',function(e){
      obj.hello = e.target.value;
    })
</script>

將數(shù)據(jù)data變成可觀察(observable)

function observer(val) {
  Object
    .key
    .forEach((val) => {
       defineReactive(val, key, value[key], cb)
    })
}
function defineReactive(obj, key, val, cb) {
  Object.defineProperty(obj, key, {
      enumerable: true,
      configurable: true,
      get: () => {
        /*....依賴收集等....*/
            /*Github:https://github.com/answershuto*/
      },
      set: newVal => {
        cb();/*訂閱者收到消息的回調(diào)*/
      }
   })
}
class Vue {
   constructor(options) {
      this._data = options.data;
      observer(this._data, options.render)
    }
 }
let app = new Vue({
    el: '#app',
    data: {
        text: 'text',
        text2: 'text2'
    },
    render(){
        console.log("render");
    }
})

為了便于理解颊乘,首先考慮一種最簡單的情況,不考慮數(shù)組等情況醉锄,代碼如上所示乏悄。在initData中會(huì)調(diào)用observe這個(gè)函數(shù)將Vue的數(shù)據(jù)設(shè)置成observable的。當(dāng)_data數(shù)據(jù)發(fā)生改變的時(shí)候就會(huì)觸發(fā)set恳不,對(duì)訂閱者進(jìn)行回調(diào)(在這里是render)檩小。

那么問題來了,需要對(duì)app._date.text操作才會(huì)觸發(fā)set烟勋。為了偷懶规求,我們需要一種方便的方法通過app.text直接設(shè)置就能觸發(fā)set對(duì)視圖進(jìn)行重繪。那么就需要用到代理卵惦。

代理

我們可以在Vue的構(gòu)造函數(shù)constructor中為data執(zhí)行一個(gè)代理proxy阻肿。這樣我們就把data上面的屬性代理到了vm實(shí)例上。

_proxy(options.data);/*構(gòu)造函數(shù)中*/

/*代理*/
function _proxy (data) {
   const that = this;
   Object.keys(data).forEach(key => {
       Object.defineProperty(that, key, {
           configurable: true,
           enumerable: true,
           get: function proxyGetter () {
               return that._data[key];
           },
           set: function proxySetter (val) {
               that._data[key] = val;
           }
       })
   });
}

我們就可以用app.text代替app._data.text了沮尿。

下面是一個(gè)模擬Vue數(shù)據(jù)綁定的方法


image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丛塌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赴邻,老刑警劉巖印衔,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異乍楚,居然都是意外死亡当编,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門徒溪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來忿偷,“玉大人,你說我怎么就攤上這事臊泌±鹎牛” “怎么了?”我有些...
    開封第一講書人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵渠概,是天一觀的道長茶凳。 經(jīng)常有香客問我,道長播揪,這世上最難降的妖魔是什么贮喧? 我笑而不...
    開封第一講書人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮猪狈,結(jié)果婚禮上箱沦,老公的妹妹穿的比我還像新娘。我一直安慰自己雇庙,他們只是感情好谓形,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疆前,像睡著了一般寒跳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竹椒,一...
    開封第一講書人閱讀 49,784評(píng)論 1 290
  • 那天童太,我揣著相機(jī)與錄音,去河邊找鬼胸完。 笑死书释,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的舶吗。 我是一名探鬼主播征冷,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼择膝,長吁一口氣:“原來是場噩夢啊……” “哼誓琼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤腹侣,失蹤者是張志新(化名)和其女友劉穎叔收,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體傲隶,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡饺律,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跺株。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片复濒。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖乒省,靈堂內(nèi)的尸體忽然破棺而出巧颈,到底是詐尸還是另有隱情,我是刑警寧澤袖扛,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布砸泛,位于F島的核電站,受9級(jí)特大地震影響蛆封,放射性物質(zhì)發(fā)生泄漏唇礁。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一惨篱、第九天 我趴在偏房一處隱蔽的房頂上張望盏筐。 院中可真熱鬧,春花似錦妒蛇、人聲如沸机断。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽吏奸。三九已至,卻和暖如春陶耍,著一層夾襖步出監(jiān)牢的瞬間奋蔚,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國打工烈钞, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留泊碑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓毯欣,卻偏偏與公主長得像馒过,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子酗钞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 請(qǐng)看下面這篇http://www.reibang.com/p/f6af9ab5a8f7
    HelenYin閱讀 494評(píng)論 3 4
  • 這方面的文章很多腹忽,但是我感覺很多寫的比較抽象来累,本文會(huì)通過舉例更詳細(xì)的解釋。(此文面向的Vue新手們窘奏,如果你是個(gè)大牛...
    Ivy_2016閱讀 15,375評(píng)論 8 64
  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,336評(píng)論 8 265
  • 室友在看我的少女時(shí)代嘹锁,我沒有加入。 我不想看着裹,是因?yàn)槲夷莻€(gè)時(shí)間遇到了你领猾,雖然后來我弄丟了你。 所以我拒絕看一切有關(guān)...
    塔卡閱讀 166評(píng)論 0 0
  • 對(duì)于一個(gè)自由職業(yè)者來說骇扇,有時(shí)很羨慕別人的年會(huì)摔竿。而今年,我居然也有機(jī)會(huì)參加年會(huì)少孝!這是一次別開生面的年會(huì)拯坟。它不是一家公...
    明媚Sopy閱讀 447評(píng)論 2 4