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