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="//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文檔-偵聽器