Vue的數據雙向綁定和Object.defineProperty()


  Vue是前端三大框架之一,也被很多人指責抄襲,說他的兩個核心功能,一個數據雙向綁定,一個組件化分別抄襲angular的數據雙向綁定和react的組件化思想,咱們今天就不談這種大是大非,當然我也沒到達那個能力。就來簡單的說說這個數據雙向綁定。

  Vue的數據雙向綁定和angular的數據綁定的原理完全不一樣,Angular是用的數據臟檢測,當Model發生變化,會檢測所有視圖是否綁定了相關數據,再更改視圖,其本質就是循環遍歷,發現與更改數據相關的視圖,然后將其更新,性能上有點差。而Vue使用的發布訂閱模式,是點對點的綁定數據,其本質就是我們今天要談論的這個方法:Object.defineProperty()

  我們先來看看他的用法:通過這個方法為對象設置的屬性可以控制他的很多行為,如:

 

var obj = {}
    obj.sex = 'men'
    Object.defineProperty(obj,'height',{
        enumerable:true, // 是否可枚舉,默認為false
        // writable:false, // 默認為false,不可寫入,即使下面寫入了,遍歷該對象也遍歷不到
        // value:'jhon', //默認值
        configurable:true, // 是否可刪除,默認false。
        set:function(val){
            console.log("設置值",val)
            _height = val
        },
        get:function(){
            console.log("獲取值")
            return _height
        }
    })
    obj.height = 100
    console.log(obj)
    console.log(1,obj.height);
    console.log(2,obj._height)

    
    delete obj._height;
    console.log(obj)
    for (var k in obj){
        console.log(k)
        console.log(obj[k]);
    }

 

enumerable控制該屬性是否可枚舉,默認為false,不可枚舉,通過for in遍歷該對象可以發現,是不能遍歷出enumerable為false的屬性的,但是仍然可以通過對象點的方式來訪問該屬性。

writable控制屬性是否可以被賦值,默認為false。盡管通過對象點的方式賦值,也是遍歷不出來的。

value設置該變量的默認值,注意,盡管writable為false的時刻,該值也是生效的,因為這個屬性只是控制他是否可以被賦值,並不能阻止他有默認值。

configurable控制該變量是否可刪除,默認為false,我們可以通過delete關鍵字來測試下,發現盡管使用delete刪除了該變量,for in 還是可以遍歷出來,說明是不能刪除的,當其值為true則可以。

  既然談到delete,就小小的普及下關於他的知識:

  1. delete關鍵字可以用來刪除沒有使用var聲明的變量
  2. delete關鍵字還可以用來刪除對象的屬性
  3. delete關鍵字擁有返回值,表示刪除是否成功,但是不可靠!(即對於一些不可以刪除的屬性,他刪除后沒有達到效果,但結果依然為true)
set和get方法:這兩個方法會在改變量設置值和獲取值時自動調用,但是這兩個方法不能和writable以及value一起使用,否則會報錯。當這兩個方法只設置一個時,就是對應着只讀或只寫屬性。
   set方法里面設置一個變量接收將要設置的值時,可以用其他的名字,如:_height,也可以和該變量同名,如height,但是不管怎么,這個變量都不屬於該對象,在外面通過對象點的方式是訪問不到的,而只能訪問到調用Object.defineProperty()方法設置的那個變量,即他的第二個參數。並且在打印該對象的時候,你會發現height屬性后面有個(。。。),並沒有直接顯示該屬性,以后碰到這樣的,就說明他是設置了set或get方法,如下圖

 

  細心的同學會發現,Vue 的data屬性里面的所有屬性都同時具有set和get方法,而Vue正式通過這種機制,檢測變量的讀取,從而實現與他綁定的視圖的更新,這種效率毫無疑問比angular是高。
  set和get方法在Vue中的第一次應用:當想定義個屬性,而這個屬性又得經過一些轉換,才是我們要的值,就可以向下面這樣去定義。調用的時候就和其他變量一樣調用即可,如:this.end_date
get end_date () {
            if (this.local_time.length) {
              return toEST(this.local_time[1])
            } else {
              return ''
            }
          }

 

  這里關於數據雙向綁定的原理就不做進一步深究了,其實是我自己還理解的不夠深,想進一步了解的同學,可以參考這篇文章。 http://www.cnblogs.com/kidney/p/6052935.html?utm_source=gold_browser_extension


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM