一文搞懂Vue中computed和watch的區(qū)別
一、computed介紹
computed 用來監(jiān)控自己定義的變量,該變量在 data 內沒有聲明,直接在 computed 里面定義,頁面上可直接使用。
//基礎使用
{{msg}}
<input v-model="name" />
//計算屬性
computed:{
msg:function(){
return this.name
}
}在輸入框中,改變 name 值得時候,msg 也會跟著改變。這是因為 computed 監(jiān)聽自己的屬性 msg,發(fā)現 name 一旦變動,msg 立馬會更新。
注意:msg 不可在 data 中定義,否則會報錯。
1.1、get 和 set 用法
<input v-model="full" ><br>
<input v-model="first" > <br>
<input v-model="second" >
data(){
return{
first:'美女',
second:'姐姐'
}
},
computed:{
full:{
get(){ //回調函數 當需要讀取當前屬性值是執(zhí)行,根據相關數據計算并返回當前屬性的值
return this.first + ' ' + this.second
},
set(val){ //監(jiān)視當前屬性值的變化,當屬性值發(fā)生變化時執(zhí)行,更新相關的屬性數據
let names = val.split(' ')
this.first = names[0]
this.second = names[1]
}
}
}get 方法:first 和 second 改變時,會調用 get 方法,更新 full 的值。
set 方法:修改 full 的值時,會調用 set 方法,val 是 full 的最新值。
1.2、計算屬性緩存
我們通過方法,拼接數據,也可以實現該效果,代碼如下。
<div> {{ full() }} </div>
data(){
return{
first:'美女',
second:'姐姐'
}
},
methods:{
full(){
return this.first + ' ' + this.second
}
},一個頁面內,數據有可能多次使用,我們把 computed 和 method 兩個方法放一起實現,并把這個數據在頁面內多次引用,試看以下效果。
<div>
computed計算值:
{{full}} {{full}} {{full}} {{full}}
</div>
<div>
methods計算值: {{fullt}} {{fullt}} {{fullt}} {{fullt}}
</div>
data(){
return{
first:'美女',
second:'姐姐'
}
},
computed:{
full:function(){
console.log('computed')
return this.first + ' ' + this.second
}
},
methods:{
fullt(){
console.log('方法')
return this.first + ' ' + this.second
}
}運行結果為:

根據結果,我們不難發(fā)現,根據方法獲取到的數據,使用幾次就需要重新計算幾次,但計算屬性不是,而是基于它們的響應式依賴進行緩存的,之后依賴屬性值發(fā)生改變的時候,才會重新計算。由于它計算次數少,所以性能更高些。
二、watch介紹
watch 是監(jiān)測 Vue 實例上的數據變動,通俗地講,就是檢測 data 內聲明的數據。不僅可以監(jiān)測簡單數據,還可以監(jiān)測對象或對象屬性。
Demo1:監(jiān)測簡單數據
<input v-model="first" > <br>
data(){
return{
first:'美女',
}
},
watch:{
first( newVal , oldVal ){
console.log('newVal',newVal) // first 的最新值
console.log('oldVal',oldVal) // first上一個值
}
},
// 修改 first的值的時候,立馬會打印最新值Demo2:監(jiān)測對象
監(jiān)聽對象的時候,需要使用深度監(jiān)聽。
<input v-model="per.name">
data(){
return{
per:{
name:'倩倩',
age:'18'
}
}
},
watch:{
per:{
handler(oldVal,newVal){
console.log('newVal',newVal)
console.log('oldVal',oldVal)
},
deep:true,
}
},修改 per.name 的時候,發(fā)現 newVal 和 oldVal 的值是一樣的,是因為他們存儲的指針指向的是同一個地方,所以深度監(jiān)聽雖然可以監(jiān)聽到對象的變化,但是無法監(jiān)聽到具體的是哪個屬性發(fā)生變化了。
Demo3:監(jiān)聽對象的單個屬性
// 方法1:直接引用對象的屬性
<input v-model="per.name">
data(){
return{
per:{
name:'倩倩',
age:'18'
}
}
},
watch:{
'per.name':function(newVal,oldVal){
console.log('newVal->',newVal)
console.log('oldVal->',oldVal)
}
},也可以借助 computed 作為中間轉換,如下:
// 方法2:借助computed
<input v-model="per.name">
data(){
return{
per:{
name:'倩倩',
age:'18'
}
}
},
watch:{
perName(){
console.log('name改變了')
}
},
computed:{
perName:function(){
return this.per.name
}
},Demo4:監(jiān)聽 props 組件傳過來的值
props:{
mm:String
},
//不使用 immediate
watch:{
mm(newV,oldV){
console.log('newV',newV)
console.log('oldV',oldV)
}
}
//使用 immediate
watch:{
mm:{
immediate:true,
handler(newV,oldV){
console.log('newV',newV)
console.log('oldV',oldV)
}
}不使用 immediate 時,第一次加載頁面時,watch 監(jiān)聽的 mm 中的打印并沒有執(zhí)行。
使用 immediate 時,第一次加載時也會打印結果:newV 11 oldV undefined。
immediate 主要作用就是組件加載時,會立即觸發(fā)回調函數。
三、兩者區(qū)別
3.1、對于 computed
- computed 監(jiān)控的數據在 data 中沒有聲明
- computed 不支持異步,當 computed 中有異步操作時,無法監(jiān)聽數據的變化
- computed 具有緩存,頁面重新渲染,值不變時,會直接返回之前的計算結果,不會重新計算
- 如果一個屬性是由其他屬性計算而來的,這個屬性依賴其他屬性,一般使用 computed
- computed 計算屬性值是函數時,默認使用get方法。如果屬性值是屬性值時,屬性有一個get和set方法,當數據發(fā)生變化時會調用set方法。
computed:{
//屬性值為函數
perName:function(){
return this.per.name
},
//屬性值為屬性值
full:{
get(){ },
set(val){ }
}
},3.2、對于 watch
- 監(jiān)測的數據必須在 data 中聲明或 props 中數據
- 支持異步操作
- 沒有緩存,頁面重新渲染時,值不改變時也會執(zhí)行
- 當一個屬性值發(fā)生變化時,就需要執(zhí)行相應的操作
- 監(jiān)聽數據發(fā)生變化時,會觸發(fā)其他操作,函數有兩個參數:
immediate :組件加載立即觸發(fā)回調函數
deep:深度監(jiān)聽,主要針對復雜數據,如監(jiān)聽對象時,添加深度監(jiān)聽,任意的屬性值改變都會觸發(fā)。
注意:對象添加深度監(jiān)聽之后,輸出的新舊值是一樣的。
computed 頁面重新渲染時,不會重復計算,而 watch 會重新計算,所以 computed 性能更高些。
四、應用場景
當需要進行數值計算,并且依賴于其它數據時,應該使用 computed ,因為可以利用 computed 的緩存特性,避免每次獲取值時都要重新計算。
當需要在數據變化時執(zhí)行異步操作或開銷較大的操作時,應該使用 watch,computed 不支持異步。如果需要限制執(zhí)行操作的頻率,可借助 computed 作為中間狀態(tài)。
到此這篇關于一文搞懂Vue中computed和watch的區(qū)別的文章就介紹到這了,更多相關Vue computed watch內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Vue3使用Suspense優(yōu)雅地處理異步組件加載的示例代碼
Vue3是Vue.js的最新版本,它帶來了許多令人興奮的新特性和改進,其中一個重要的特性是Suspense,它為我們提供了一種優(yōu)雅地處理異步組件加載和錯誤處理的方式,本文給大家介紹了Vue3使用Suspense優(yōu)雅地處理異步組件加載的示例,需要的朋友可以參考下2024-01-01

