一,前言
上一篇介紹了Vue的方法和事件,在Vue實例methods選項中對方法進行定義
這一篇介紹Vue的計算屬性,計算屬性定義在vue實例compute選項中,
compute計算屬性功能上和methods中的方法很相似,
稍後我們會探討計算屬性的使用及計算屬性和方法的區別
二,引入計算屬性
之前介紹了插值(即雙大括號表達式),支持簡單的表達式和過濾器可以對值做一些簡單運算和文本轉換
模板內的表達式非常便利,但是設計它們的初衷是用於簡單運算的
在模板中放入太多的邏輯會讓模板過重且難以維護
例如:
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
過長的表達式中包含了3個操作,模板不再是簡單的聲明式邏輯,
複雜的邏輯會使代碼變得難以理解(可讀性差)和維護,且無法複用
所以,對於任何複雜邏輯,都應使用計算屬性
三,使用計算屬性
對上邊的例子使用計算屬性進行改寫:
<div id="app">
<!--輸出DEF,ABC-->
{{ reverseText }}
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data: {
text: 'ABC,DEF'
},
computed: {
reverseText: function () {
// this指向當前vue實例
return this.text.split(',').reverse().join(',')
}
}
})
</script>
使用Vue計算屬性對屬性應用計算邏輯,
計算屬性以函數形式聲明在Vue實例的computed選項內,最終返回計算後的結果
四,計算屬性在購物車的應用
在電商項目中,計算屬性的一個典型使用場景就是購物車頁面
通過勾選購物車中的商品或修改商品購買數量計算總價
<div id="app">
商品總價 : {{ prices }}
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data: {
books: [
{name: 'Vue.js', price:50},
{name: 'Javascript', price:30},
{name: 'Css', price:40},
{name: 'Html', price:60}
]
},
computed: {
prices: function () {
var totlePrice = 0;
for(var i=0; i<this.books.length; i++){
totlePrice += this.books[i].price;
}
return totlePrice;
}
}
})
</script>
簡單使用books模擬購物商品,頁面顯示計算屬性返回的商品總價
運行結果:
頁面初始化顯示由計算屬性計算得到的商品總價
通過devTools修改第一個商品的價格,由50變化到51,此時會觸發計算屬性,更新價格顯示
再通過devTools刪除第一個商品,此時會觸發計算屬性,更新價格顯示
結論:
在計算屬性中所依賴的Vue實例數據有任何變化,都觸發計算屬性重新執行,更新視圖顯示
五,計算屬性中的getter和setter
實際上,每一個計算屬性都包含一個getter和setter,默認只使用getter進行數據讀取
我們也可以提供setter函數,當手動修改計算屬性值時會觸發setter方法
引用一個經典的例子進行說明:
<div id="app">
姓名:<input type="text" v-model="fullName">
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data: {
firstName:"Jack",
lastName:"Green"
},
computed: {
fullName:{
// getter
get: function () {
return this.firstName + " " + this.lastName;
},
// setter
set: function (newVal){
var name = newVal.split(' ');
this.firstName = name[0];
this.lastName = name[1];
}
}
}
})
</script>
運行結果:
初始化通過計算方法得到fullName顯示
修改fullName值,觸發setter方法,重新對firstName和lastName賦值
對於計算屬性,大多數情況下不必將getter和setter都聲明,
實際業務中很少使用到setter方法,所以聲明計算屬性時,直接使用默認寫法即可
注意:
計算屬性可以依賴其他計算屬性,並且計算屬性可以依賴當前Vue實例以外的其他Vue實例數據
六,computed VS methods
對比computed和methods,他們之中的方法都可以實現相同的作用
將本篇由computed實現的Demo改寫爲methods實現:
<div id="app">
<!--輸出DEF,ABC-->
{{ reverseText() }}
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#app',
data: {
text: 'ABC,DEF',
},
methods:{
reverseText: function () {
// this指向當前vue實例
return this.text.split(',').reverse().join(',')
}
}
})
</script>
這裏沒有使用計算屬性,改用在methods定義的方法實現了相同的效果
computed 和 methods的區別
computed 和 methods雖然都可以實現對數據的計算,但兩者有一定的區別:
methods:
使用methods方法可以接受外部傳參,使用更加靈活
computed:
計算屬性computed的亮點在於:它能夠依賴緩存
當計算屬性所依賴的數據發生改變時,纔會重新觸發計算屬性方法執行
所以對於較複雜或消耗效率的計算,一定要採用計算屬性
使用methods的方法,每次頁面刷新都會觸發方法的執行
而使用計算屬性,只要依賴的數據沒有變化,就會直接從緩存中讀取結果,不需要重新計算
這種做法可以提升效率更可以帶來更好的用戶體驗
但是,並不是使用computed就一定更好
computed: {
now: function(){
return Data.now();
}
}
由於Data.now並不是響應式依賴,所以計算屬性now不會更新
但是methods不同,只要重新渲染就會執行
所以,使用methods還是計算屬性主要取決於是否需要緩存
當對大數組遍歷或計算量較大時,應使用計算屬性,不需要緩存使用methods
七,結尾
這一篇主要介紹了計算屬性的使用,methods的對比及適用場景
計算屬性基於緩存,在所依賴的數據發生變化時,會觸發執行刷新頁面顯示
在Vue還通過watch選項提供了一個偵聽器,可以自定義對數據的監聽事件來響應數據的變化
下一篇介紹Vue選項watch偵聽器