詳解Vue中的computed和watch
- 前言
- 原理
- computed
- computed特點
- computed有幾種創建方式
- 應用
- Watch
- Watch有幾種創建方式
- Watch主要內容
- Watch特性
- 應用場景
- computed和Watch區別
前言
在Vue當中,watch和computed都可以實現監聽的效果,本文主要是圍繞watch和computed這兩個屬性來進行深入的講解,講解內容包括它們的原理、實現方式、各自優劣以及區別。
原理
computed
概念:通過對某個屬性值進行一系列計算,讓該屬性值為一個新的值。在計算過程中,可以調用多個其他屬性值用于計算。
computed又稱計算屬性,它主要作用就是用于在Vue當中監聽某個屬性的變化。舉個例子來分別演示沒有computed和用了computed的vue實例。
需求:讓兩個數字相加求解。
沒有用computed:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!--1.導入Vue的庫文件--><script src="vue.js"></script></head><body><div id="app">a:<input type="number" v-model="a"><br>b:<input type="number" v-model="b"><br><button @click="btn">計算</button><div>相加等于:{{ c }}</div></div><!--2.創建Vue的實例對象--><script>//創建Vue的實例const vm = new Vue({// el屬性是固定寫法。// 表示當前的VM實例要控制頁面上的哪上區域,收接的是一個選擇器。el: "#app",data: {a: '',b: '',c: null},methods: {btn() {this.c = parseFloat(this.a) + parseFloat(this.b)}}})</script></body>
</html>
在上述代碼中,我們可以發現,求解是用了一個按鈕實現,首先我們創建了Vue實例,然后創建三個變量a,b,c,c是結果,a,b是兩個數字,用v-model進行數據綁定后,輸入點擊按鈕后就能出現結果。那么如果使用計算屬性computed,也可以用另一種方式實現相同的效果。計算操作在計算屬性中進行實現。
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!--1.導入Vue的庫文件--><script src="vue.js"></script></head><body><div id="app">a:<input type="number" v-model="a"><br>b:<input type="number" v-model="b"><br><div>結果:{{ c }}</div></div><!--2.創建Vue的實例對象--><script>//創建Vue的實例const vm = new Vue({// el屬性是固定寫法。// 表示當前的VM實例要控制頁面上的哪上區域,收接的是一個選擇器。el: "#app",data: {a: '',b: '',},computed:{c(){return parseFloat(this.a)+parseFloat(this.b);}}})</script></body>
</html>
在上述代碼中,我們可以看到,計算屬性代替了按鈕實現了相同的計算功能。那么同時我們發現,計算屬性要放在computed節點下才生效,而節點下的計算屬性,語法格式和定義method方法的語法格式相同,這個計算屬性,會實時監聽它的屬性值是否發生改變,如果發生改變就會立即緩存,不需要任何人為操作。它在初始化時就會進行緩存,那么在上述代碼中,它的初始值就為NaN,NaN展開就為Not a Number,中文叫非數。輸入a和b的數字后,就可以看到立刻發生變化。
computed特點
- 計算屬性都放在computed節點下。
- 定義方式和方法相同。
- 只要該計算屬性的依賴屬性發生改變,它就會重新計算并進行視圖更新以及計算屬性緩存。
- 所有的計算屬性都有緩存機制,當初始化后即開始了第一次計算屬性緩存,而看到的值,實際是從緩存中拿到的。
- 惰性執行:如果不調用這個計算屬性,但是依賴項改變了,那屬性會被標記為dirty,但是它計算,只有調用了且被標記為dirty了,它才會進行計算緩存和更新操作。
- 不允許執行異步操作
computed有幾種創建方式
兩種,一種函數式,一種對象式。
function a(){} || a:{get(){},set(){}}
應用
- 當一個屬性頻繁的受其他多個屬性影響時可以被應用。
Watch
概念: 監聽器,是Vue實例的一個屬性,是用來響應數據的變化,需要在數據變化時執行異步或開銷較大的操作時,這個方式是最有用的。
大白話就是,監聽某個屬性值是否變化,如果該屬性值發生改變,則做一系列與改變有關的操作。
實例:輸入姓,輸入名,得到姓名
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><!--1.導入Vue的庫文件--><script src="vue.js"></script></head><body><div id="app">姓:<input type="text" v-model="x"><br>名:<input type="text" v-model="m"><br><div>結果:{{ xm }}</div></div><!--2.創建Vue的實例對象--><script>//創建Vue的實例const vm = new Vue({// el屬性是固定寫法。// 表示當前的VM實例要控制頁面上的哪上區域,收接的是一個選擇器。el: "#app",data: {x: '李',m: '華',xm:''},watch:{x:{handler(oldValue,newValue){this.xm=newValue+this.m}},m:{handler(oldValue,newValue){this.xm=this.x+newValue;}}}})</script></body>
</html>
首先我們分析這個需求,如果把這個需求放在計算屬性中,我們發現只需要一個計算屬性result就可以實現,而監聽需要做兩個,因為我們要監聽的是姓和名兩個屬性值,這和計算屬性和判斷依賴項是否改變是不同的,這也決定了它們適用的方向不同。
Watch有幾種創建方式
五種:函數、對象、數組、函數名
常用的還是第一種:
watch:{監聽屬性名:{handler(監聽前值,監聽后值){代碼邏輯}}}
Watch主要內容
handler:回調函數,也就是監聽到變化后執行的函數。
deep:確認是否深入監聽,假設有個深層對象,當它很多層內的數據發生變化,是否依舊能監聽到且執行回調函數,如果想監聽到,可以開啟深度監聽。
immediate:默認是false,false則初始化頁面后不調用監聽回調函數,true則第一次進入頁面就調用回調函數且綁定值。
Watch特性
- 默認初次進入頁面不調監聽函數(immediate:true解決)
- 一個監聽函數只能監聽一個屬性值
- 默認當對象屬性值發生改變不調監聽(deep:true解決)
- 允許執行異步操作,比如調用一個API。
應用場景
- 一次只能監聽一個數據,并處理數據相關的代碼邏輯。
- 百度聯想詞
- 復雜的業務邏輯或調用異步API,如AJAX。
computed和Watch區別
下面簡稱computed為c,Watch為w。
- c發生改變是因為依賴項改變,所以它能監聽幾個屬性取決于它有幾個依賴屬性,所以它能監聽一個或多個屬性,w一次只能監聽一個屬性。
- 因為c的值是被同步計算出來的,先判斷依賴是否改變,改變則計算,計算后緩存,緩存后顯示,所以c不能異步操作,w能異步。
- c要判斷依賴項是否改變,改變后需要計算才能緩存,而watch監聽到改變就立刻執行相關操作。
- c可以類似data直接訪問到,watch不能。
- 所以說計算多個屬性時可以用computed,監聽一個屬性或處理異步或邏輯較難業務可以用watch。