關於vue的計算屬性以及雙向綁定的原理理解(vue2.x)以及vue3.0

vue的計算屬性:

1.什麼是計算屬性?                 

計算屬性的目的是用於對數據進行簡單運算的,若在模板中放過多的計算邏輯會致使模板難以維護。html

計算屬性是基於它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時纔會從新求值。vue

2.計算屬性如何使用?

1.在一個計算屬性裏能夠完成各類複雜的邏輯,包括運算、函數調用等,只要最終返回一個結果就能夠。瀏覽器

 computed: {
        reverseText: function(){
            return app1.text.split('').reverse().join('');  //對數據進行計算,將reverseText放進模板中,只要依賴的數據發生變化就會改變
        }
    }

2.計算屬性還能夠依賴多個Vue 實例的數據,只要其中任一數據變化,計算屬性就會從新執行,視圖也會更新。緩存

兩個小方面是計算屬性能夠依賴其餘計算屬性;  是計算屬性不只能夠依賴當前Vue 實例的數據,還能夠依賴其餘實例的數據。性能優化

    <div id="app1"></div>
    <div id="app2">{{ reverseText}}</div>
var app1 = new Vue({
   el: '#app1',
 data: {
      text: 'computed'
    }
});

var app2 = new Vue({
    el: '#app2',
    computed: {
        reverseText: function(){
            return app1.text.split('').reverse().join('');  //使用app1的數據進行計算
        }
    }
});

每個計算屬性都包含一個getter 和一個setter ,計算屬性會默認使用getter,相關用法以下:app

var vm = new Vue({
    el: '#demo',
    data: {
        firstName: 'Foo',
        lastName: 'Bar'
    },
    computed: {
        fullName: {
            // getter
            get: function () {
                return this.firstName + ' ' + this.lastName
            },
            // setter
            set: function (newValue) {
                var names = newValue.split(' ');
                this.firstName = names[0];
                this.lastName = names[names.length - 1];
            }
        }
    }
});

在咱們平常使用中,一般不用特地聲明setter,當手動修改計算屬性的值就像修改一個普通數據那樣時,就會觸發setter 函數,執行一些自定義的操做ide

var vm = new Vue({
    el: '#demo',
    data: {
        firstName: 'Foo',
        lastName: 'Bar'
    },
    computed: {
        fullName: {
            // getter
            get: function () {
                return this.firstName + ' ' + this.lastName
            },
            // setter
            set: function (newValue) {
                var names = newValue.split(' ');
                this.firstName = names[0];
                this.lastName = names[names.length - 1];
            }
        }
    }
});
//如今再運行 vm.fullName = 'John Doe' 時,setter 會被調用,vm.firstName 和 vm.lastName 也會相應地被更新。

絕大多數狀況下,咱們只會用默認的getter 方法來讀取一個計算屬性,在業務中不多用到setter,因此在聲明一個計算屬性時,能夠直接使用默認的寫法,沒必要將getter 和setter 都聲明。函數

 

總結:當一個屬性data須要進行邏輯性的運算和判斷時,便出現了計算屬性(computed),計算屬性一個最大的特色就是會判斷依賴的數據是否改變來判斷,若未改變便會利用以前儲存的數據,不用再獲取,雖然方法也能夠實現邏輯的運算,但不會監聽數據是否發生了變化,會進行重複性的請求,因此計算屬性更加優化和智能。性能

computed vs methods 優化

  -計算屬性是基於它們的依賴進行緩存的。

  -計算屬性只有在它的相關依賴發生改變時纔會從新求值

 

相關函數的案例轉自:http://www.javashuo.com/article/p-svqnaisq-cr.html



雙向綁定的原理:

 一個普通的 JavaScript 對象傳入 Vue 實例做爲 data 選項,Vue 將遍歷此對象全部的屬性,並使用 defineProperty 把這些屬性所有轉爲 getter/setter

Object.defineProperty 是 ES5 中一個沒法 shim 的特性,這也就是 Vue 不支持 IE8 以及更低版本瀏覽器的緣由

 // 給對象添加屬性的語法
        var data = {}

        // IE8和以前瀏覽器不支持
        // 一種給對象添加屬性的方式
        // 給obj添加name屬性
        // 這樣加屬性的好處是,能夠監聽屬性的賦值和取值
        // 當對象給這個屬性賦值時,就會調用set方法
        // 取值時就會調用get方法
        Object.defineProperty(data,'name',{

            get(){
                // console.log('取值了');
                //必須在get最後寫return _屬性名
                return _name;
            },

            // value是你賦值時是什麼值,就傳過來什麼
            set(value){
                // console.log('set');
                
                // 必須寫_屬性名 = value
                _name = value
                // console.log(data.name);
                var list = document.querySelectorAll('[v-bind]')
                for(var i = 0; i < list.length; i++){
                    list[i].innerHTML = value;
                }
            }
        })

這樣就能夠經過get和set來監聽數據的獲取和傳值

上面就是目前Vue2.x的雙向綁定原理,但即將發佈的Vue3.0的雙向綁定原理則採用了新的技術,就是proxy

proxy

 

let data = {}
  
  // new proxy對象
  let proxyData = new Proxy(data,{
    get(obj,prop){      
      console.log('get')
      console.log(obj)
      console.log(prop)
      return obj[prop]
    },
    set(obj,prop,value){    //obj:綁定的對象   //prop:賦的屬性   //value:屬性值
      obj[prop]= value
      console.log('set')
      console.log(obj)
      console.log(prop)
      console.log(value)
    }
  })
//obj:綁定的對象   //prop:賦的屬性   //value:屬性值
new的proxy對象綁定的數據data,只要是data任何屬性發生改變都會調用
無論是這個對象的什麼屬性都會調用set或者get

 有關proxy與defineProperty的區別:

 1.Proxy有多達13種攔截方法,不限於apply、ownKeys、deleteProperty、has等等是Object.defineProperty不具有的。

 2.Proxy返回的是一個新對象,咱們能夠只操做新的對象達到目的,而Object.defineProperty只能遍歷對象屬性直接修改。

 3.Proxy做爲新標準將受到瀏覽器廠商重點持續的性能優化,也就是傳說中的新標準的性能紅利。

 4.Proxy的劣勢就是兼容性問題,並且沒法用polyfill磨平,所以Vue的做者才聲明須要等到下個大版本(3.0)才能用Proxy重寫。

 

相關詳細資料參考:https://www.jianshu.com/p/2df6dcddb0d7

相關文章
相關標籤/搜索