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


vue的計算屬性:

1.什么是計算屬性?                 

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

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

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,相關用法如下:

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 函數,執行一些自定義的操作

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

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

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

 

相關函數的案例轉自:https://www.cnblogs.com/chaixiaozhi/p/8688820.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

 

 

             


免責聲明!

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



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