計算屬性的目的是用於對數據進行簡單運算的,若在模板中放過多的計算邏輯會致使模板難以維護。html
計算屬性是基於它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時纔會從新求值。vue
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
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
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