1. 程式人生 > 其它 >使用computed_《computed 與 watch的區別》

使用computed_《computed 與 watch的區別》

技術標籤:使用computed

computed

computed是計算屬性的

它會根據所依賴的資料動態顯示新的計算結果計算的結果會被快取起來

computed的值在getter執行後是會被快取的。如果所依賴的資料發生改變時候,就會重新呼叫getter來計算最新的結果。

根據Vue文件例子來理解computed的使用

computed設計的初衷是為了使模板中的邏輯運算更簡單

<body>
  <div id="app">
    {{ msg.split('').reverse().join('') }}
  </div>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        msg: 'hello'
      }
    });
  </script>
</body>

我們在vue模板中會對該資料值進行反轉操作後輸出資料, 因此在頁面上就會顯示 ​'olleh'

如果頁面中的運算比這個還更復雜的話, 這個時候我們可以使用computed來進行計算屬性值。把上面的程式碼改寫成下面如下程式碼:

<body>
  <div id="app">
    <p>原來的資料: {{ msg }}</p>
    <p>反轉後的資料為: {{ reversedMsg }}</p>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'hello'
      },
      computed: {
        reversedMsg() {
          // this 指向 vm 例項
          return this.msg.split('').reverse().join('')
        }
      }
    });
  </script>
</body>

如上程式碼, 我們在​computed​中聲明瞭一個計算屬性​​​​reversedMsg​。我們提供的​​​​reversedMsg​函式, 將用作屬性 ​vm.reversedMsg​​​的​getter​函式

我們也可以開啟控制檯, 當我們修改 vm.msg 的值後, vm.reversedMsg 的值也會發生改變,如下控制檯列印的資訊可知:

f6296e56ea2ca9558f55679eae2b3679.png

我們的​vm.reversedMsg​的值依賴於​vm.msg​的值,當​vm.msg​的值發生改變時, ​vm.reversedMsg​的值也會得到更新

computed應用場景

1. 適用於一些重複使用資料或複雜及費時的運算。我們可以把它放入​computed

​中進行計算, 然後會在​computed​中快取起來, 下次就可以直接獲取了。

2. 如果我們需要的資料依賴於其他的資料的話, 我們可以把該資料設計為​computed​中。


watch的用法

watch​用於偵聽data​的資料。

當​data​資料發生變化,執行函式。在函式中會傳入​newVal​和​oldVal​兩個引數

watch​屬性可以是字串、函式、物件、陣列

擁有deep,immediate兩屬性

示例

new Vue({
  data: {
    n: 0,
    obj: {
      a: "a"
    }
  },
  template: `
    <div>
      <button @click="n += 1">n+1</button>
      <button @click="obj.a += 'hi'">obj.a + 'hi'</button>
      <button @click="obj = {a:'a'}">obj = 新物件</button>
    </div>
  `,
  watch: {
    n() {
      console.log("n 變了");
    },
    obj() {
      console.log("obj 變了");
    },
    "obj.a": function() {
      console.log("obj.a 變了");
    }
  }
}).$mount("#app");

點選​n+1​ : 打印出​“n 變了”

點選​obj.a + 'hi'​ : 打印出​“obj.a 變了”​,不列印​"obj 變了"

不點選​obj.a + 'hi'​ , 點選​obj = 新物件​ : 打印出​"obj 變了"​,不列印​"obj 變了"

說明watch的監聽方式是:簡單資料型別看值,複雜資料型別(物件)看地址

那我想通過監聽​obj​也能​obj.a​變化可以嗎?

答:請使用​deep

使用​deep​屬性

watch: {
    n() {
      console.log("n 變了")
    },
    obj() {
      console.log("obj 變了")
      deep: ture       // 可以監聽到obj物件的所有內部屬性
    },
    "obj.a": function() {
      console.log("obj.a 變了")
    }
  }

點選​obj.a + 'hi' ​: 打印出​“obj.a 變了”​和​ "obj 變了"

當deep:true 會監聽到obj物件的所有內部屬性,預設值為false

immediate屬性

new Vue({
  data: {
    firstName: 'Jacky',
    lastName: 'Lee',
    fullName: ''
  },
  watch: {
    firstName: {
      handler: 'change'
    }
  },
  template: `
    <div>
      {{fullName}}
      <button @click="firstName='John'">改名字</button>
    </div>
  `,
  methods: {
    change() {
      this.fullName =  this.firstName + ' ' + this.lastName      
    }
  }
}).$mount("#app");

執行上面程式碼,頁面啥也沒有,然後點選“改名字”,頁面顯示 ​John Lee

這因為watch不會監聽第一次變化

改造一下

watch: {
    firstName: {
      handler: 'change',
      immediate: ture
    }
}

當 immediate:true 時,回撥函式會在監聽開始後立刻執行,可以監聽到到第一次變化。

總結:

  • computed是用來計算一個值的,使用時不需要加括號,可以直接當屬性使用。computed擁有依賴快取特性,如果依賴值不變,computed不會重新計算
  • watch是用來監聽的,有兩個選項,immediate 和 deep,當immediate: true時,表示會在第一次執行是執行這個函式,當 deep:true時,如果監聽一個物件,會同時監聽其內部屬性。watch沒有依賴快取特性。