Vue系列之computed使用詳解(附demo,不定期更新)

付出發表於2018-01-31

前言:工作中用Vue技術開發專案有一段時間了,獨立開發完成專案基本沒什麼問題。可是就是在在開發過程中遇到問題常常是通過零散的搜尋或者官方文件來解決,這樣的現象就說明自己對Vue根本沒有一套自己理解後的系統知識的框架。為了建立這套完整的Vue知識框架,開始了《我眼中的Vue》系列文章的寫作,本系列是基於Vue官方文件,其他資料教材,加上實踐經驗總結後形成的一套個人資料。文中的觀點僅供參考,如果能對你有些許幫助或者啟發,筆者則甚是欣慰。點此進入githubDemo地址

文章目錄

基礎用法:

1.計算屬性的getter函式

2.計算屬性的setter函式

3.計算屬性的cache快取屬性
複製程式碼

常見問題:

  1.計算屬性getter不執行的場景
  
  2.在v-for中使用計算屬性,起到類似"過濾器的作用"
  
  3.watch與computed的set函式的比較
複製程式碼

computed 計算屬性

定義:當其依賴的屬性的值發生變化的時,計算屬性會重新計算。反之則使用快取中的屬性值。

一個完整的計算屬性如下:

computed: {
 example: {
   get () {
     return 'example'
   },
   set (newValue) {
     console.log(newValue)
   }
 }
複製程式碼

基礎用法

1.計算屬性的getter函式

當其依賴的屬性的值發生變化的時,這個計算屬性的值也會自動更新。多用於"data,computed"的屬性。

<template>
  <div>
    <h4>測試</h4>
    <div>
      <input type="text" v-model="message" />
      <div>{{changeMessage}}</div>
    </div>
  </div>
</template>

<script>
   export default {
    data () {
       return {
         message: 'hello'
       }
     },
    computed: {
       changeMessage: {
        // 計算屬性:依賴message變化而變化  依賴沒變化就不會重新渲染;
        get () {
           return this.message + 'world'
        },
        set () {
        }
      }
     }
  }
</script>
複製程式碼

2.計算屬性的setter函式

當賦值給計算屬性的時候,將呼叫setter函式。多用於在模板元件中需要修改計算屬性自身的值的時候。

<template>
  <div>
    <h4>測試</h4>
    <div>
      {{didi}}
      {{family}}
    </div>
    <div>
      {{didiFamily}}
    </div>
  </div>

</template>

<script>
   export default {
    data () {
       return {
        didi: 'didi',
        family: 'family'
       }
     },
    computed: {
      didiFamily:{
        //getter
        get:function(){
          return this.didi + ' ' + this.family
        },
        //setter
        set:function(newValue){
          // 這裡由於該計算屬性被賦值,將被呼叫
          console.log(newValue)
          this.didi = 123
          this.family = 456
        }
      }
    },
    mounted () {
      // 賦值,呼叫setter函式
      this.didiFamily = 'John Doe'
    }
  }
</script>
複製程式碼

3.計算屬性的快取

Vue例項中被觀察的資料屬性發生了改變時才會重新執行getter,但是我們有時候計算屬性依賴實時的非觀察資料屬性,比如下面例子中的Data.now

<template>
  <div>
    <h4>測試</h4>
    <div>
      <input type="text" v-model="message" />
      <div>{{now}}</div>
    </div>
  </div>

</template>

<script>
   export default {
    data () {
       return {
         message: 'hello'
       }
     },
    computed: {
      now:{
        cache: false,
        get:function(){
          return Date.now() + this.message
        }
      }
    },
    mounted () {
      setInterval(() => {
        // 當快取開關為false的時候,定時器每次列印的時間都是不一樣的
        console.log(this.now)
      }, 500)
    }
  }
</script>
複製程式碼

常見問題

1.計算屬性getter不執行的場景

當包含計算屬性的節點被移除並且模板中其他地方沒有再引用該屬性的時候,那麼對應的計算屬性的getter函式方法不會執行

程式碼例項如下

<template>
  <div>
    <h4>測試</h4>
    <div>
      <button @click="toggleShow">Toggle Show Total Price</button>
      <p v-if="showTotal">Total Price = {{totalPrice}}</p>
    </div>
  </div>

</template>

<script>
   export default {
    data () {
       return {
        showTotal: true,
        basePrice: 100
       }
     },
    computed: {
      totalPrice () {
        return this.basePrice + 1
      }
    },
    methods: {
      toggleShow () {
        this.showTotal = !this.showTotal
      }
    }
  }
</script>
複製程式碼

2.在v-for中使用計算屬性,起到類似"過濾器的作用"

<template>
  <div>
    <h4>測試</h4>
    <div>
      <ul>
      	<li v-for="n in evenNumbers">{{n}}</li>
      </ul>
    </div>
  </div>

</template>

<script>
   export default {
    data () {
       return {
        numbers: [ 1, 2, 3, 4, 5 ]
       }
     },
    computed: {
      evenNumbers () {
        return this.numbers.filter(function (number) {
          return number % 2 === 0
        })
      }
    }
  }
</script>

複製程式碼

3.watch與computed的set函式的比較

vuex 接收 的computed ,用set監測不到變化,必須要用watch才可以生效;(原理:實質沒有改變computd的值,只是改變了get的return值 => 元件外的訪問)

v-model 改變的computed,用watch監測不到變化,必須要用computed物件中的set函式方法才能監測得到(原理:相當於每次改變了computed自身的值 => 元件內的訪問)

總結

that's all, 以上就是我目前所有的關於Vue系列的computed的理解。覺得對你開發有幫助的可以點贊收藏一波,如果我哪裡寫錯了,希望能指點出來。如果你有更好的想法或者建議,可以提出來在下方評論區與我交流。大家一起進步,共同成長。感謝[鞠躬]。

參考資料

相關文章