Vue核心技術-8,計算屬性

一,前言

上一篇介紹了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顯示
setter1

修改fullName值,觸發setter方法,重新對firstName和lastName賦值
setter2

對於計算屬性,大多數情況下不必將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偵聽器
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章