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
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