天天看點

Vue 基礎自查——watch、computed和methods的差別

1 前言

建立一個Vue執行個體時,可以傳入一個選項對象

const vm = new Vue({
  data: {
    msg: 'hello'
  },
  computed: {},
  methods: {},
  watch: {}
})
           

這個選項對象可以指定非常多的選項(或者說屬性),和資料相關的選項有:包括但不限于

data

methods

computed

watch

等等

其中

methods

computed

watch

都能通過函數來對資料進行處理或作出響應,這三者有差異,但很容易混淆

2 基礎用法

script

引入

vue.js

,下面的代碼都在如下

html

中運作

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Methods</title>
    <!-- 引入 vue.js -->
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
  </head>
  <body>
    
  </body>
  <script>
    
  </script>
</html>

           

2.1 methods 方法

methods

選項中的定義的函數稱為方法,在Vue執行個體化的過程中,

methods

對象中的方法将被混入到Vue執行個體中,成為Vue執行個體的方法。可以直接通過Vue執行個體通路這些方法

<body>
  <div id="example">
    <!-- 顯示:a:1 -->
    <p>a:{{ plus() }}</p> 
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      a: 0,
    },
    methods: {
      plus: function () {
        return this.a + 1;
      },
    },
  });
  console.log(vm); // 檢視控制台輸出的vm,可以看到它有一個方法是:plus: ƒ (),⚠️注意是方法
  console.log(vm.plus()); // 直接通過vm執行個體通路方法,輸出:1
</script>
           

需要主動調用

methods

中的函數才能執行,

a

的值改變并不能讓頁面中的

<p>a:{{plus()}}</a>

跟着更新

2.2 computed 計算屬性

computed

選項中定義的函數稱為計算屬性,在Vue執行個體化的過程中,

computed

對象中的計算屬性将被混入到Vue執行個體中,成為Vue執行個體的同名屬性。

<body>
  <div id="example">
    <!-- 顯示:a:1 -->
    <p>a:{{ plus }}</p>
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      a: 0,
    },
    computed: {
      plus: function () {
        return this.a + 1;
      },
    },
  });
  console.log(vm); // // 檢視控制台輸出的vm,可以看到它有一個屬性是:plus:1,⚠️注意是屬性
</script>
           

乍一看好像

computed

methods

功能一樣,确實在這個例子中二者展示效果相同

事實上通過列印

vm

執行個體以及通路方式已經展現出二者的一個不同之處:

  • methods

    中的函數會成為

    vm

    的方法
  • computed

    中的函數經過計算後會成為

    vm

    的同名屬性,屬性值為函數的計算結果,即傳回值

另外,和方法不同的是,計算屬性能夠跟着它依賴的資料變化而進行響應式更新,即

a

變化時,

plus

屬性也會更新

2.3 watch 偵聽器

watch

選項中的鍵值對稱為偵聽器或者說監聽屬性/監聽屬性,鍵是需要觀察的表達式,值是對應的回調函數(值還可以是其他形式,此處不展開)

在Vue執行個體化的過程中,這些需要偵聽的變量會被記錄下來,當這些變量發生變化的時候,對應的回調函數就會執行

<body>
  <div id="example">
    <!-- 顯示:a:1 -->
    <p>a:{{ a }}</p>
  </div>
</body>
<script>
  const vm = new Vue({
    el: "#example",
    data: {
      a: 0,
    },
    watch: {
      a: function () {
        console.log("a發生了變化"); // 因為a的值變了,回調函數執行
        console.log(this.a);
      },
    },
  });
  vm.a = 1; // 這裡直接手動改變a的值
</script>
           

3 三者的差別

3.1 方法 VS 計算屬性

除了

2.2

中已經提到的兩點差別之外,還有最重要的差別是:

  • 計算屬性是基于它們的響應式依賴進行緩存的

    即上文中的

    a

    發生變化時,才會重新觸發求值函數,否則多次調用都會從緩存中求值

    這對開銷較大的計算來說非常有用,可以避免重複計算

  • 方法則是調用時總會重新執行

下面用表格的形式對這兩者的差別進行總結:

methods computed
Vue執行個體化後成為vm執行個體的什麼 成為vm執行個體上的方法 成為vm執行個體上的屬性
能否根據依賴的資料進行響應式更新 不能,需要主動調用方法
能否緩存 不能,每次調用重新執行 能,依賴的資料不變,會從緩存中取值

3.2 計算屬性 VS 偵聽器

  • 首先最明顯的差別,偵聽器的命名方式是固定的,想要監聽誰,就和誰同名。而方法和計算屬性可任意命名
  • 其次,偵聽器無法主動進行通路,而另外兩者都能主動通路
  • 計算屬性和偵聽器的使用場景:

    如果某個值需要通過一個或多個資料計算得到,就使用計算屬性

    偵聽屬性主要是監聽某個值的變化,然後進行需要的邏輯處理;此外當需要在資料變化時執行異步或開銷較大的操作時,偵聽屬性就比較有用,具體例子可見vue文檔-偵聽器