Vue中watch與watchEffect的區(qū)別詳細解讀
watch和watchEffect的對比
watch函數與watchEffect函數都是監(jiān)聽器,在寫法和用法上有一定區(qū)別,是同一功能的兩種不同形態(tài),底層都是一樣的。
watch
watch顯式指定依賴數據,依賴數據更新時執(zhí)行回調函數
具有一定的惰性lazy 第一次頁面展示的時候不會執(zhí)行,只有數據變化的時候才會執(zhí)行(設置immediate: true時可以變?yōu)榉嵌栊裕撁媸状渭虞d就會執(zhí)行)
監(jiān)視ref定義的響應式數據時可以獲取到原值既要指明監(jiān)視的屬性,也要指明監(jiān)視的回調
watchEffect
watchEffect自動收集依賴數據,依賴數據更新時重新執(zhí)行自身
立即執(zhí)行,沒有惰性,頁面的首次加載就會執(zhí)行
無法獲取到原值,只能得到變化后的值
不用指明監(jiān)視哪個屬性,監(jiān)視的回調中用到哪個屬性就監(jiān)視哪個屬性
深度解析watch函數
watch函數有兩個小坑:
- 監(jiān)視reactive定義的響應式數據(該數據為一個對象,因為reactive只能定義數組或對象類型的響應式)時:oldValue無法正確獲取,會強制開啟深度監(jiān)視,deep配置不生效。
- 監(jiān)視reactive定義的響應式數據中的某個屬性時,且該屬性是一個對象,那么此時deep配置生效。
具體的watch函數的用法在下面代碼中都有所體現(xiàn),注釋詳細
<template>
<div>
<h2>當前求和為:{{sum}}</h2>
<button @click="sum++">點我+1</button>
<hr>
<h2>當前的信息為:{{msg}} </h2>
<!-- 點擊button拼接! -->
<button @click="msg+='!'">修改數據</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年齡:{{person.age}}</h2>
<h2>薪資:{{person.job.j1.salary}}</h2>
<button @click="person.name+='~'"> 修改姓名</button>
<button @click="person.age++"> 增長年齡</button>
<button @click="person.job.j1.salary++"> 增長薪資</button>
</div>
</template>
<script>
import {ref,reactive,watch,watchEffect} from 'vue'
export default {
name:'demo',
setup(){
//數據
let sum = ref(0)
let msg = ref('hello')
let person = reactive({
name:'zhangsan',
age:'18',
job:{
j1:{
salary:20
}
}
})
//監(jiān)視(三個參數,第一個是監(jiān)視的對象,第二個是監(jiān)視的回調函數,第三個是監(jiān)視的配置)
//情況一:監(jiān)視ref所定義的一個響應式數據
watch(sum,(newValue,oldValue)=>{
console.log('sum的值變化了',newValue,oldValue)
},{immediate:true,deep:true})
//immediate的值為true時表示非惰性的立即執(zhí)行的(默認情況下是false)
//deep深層次觸發(fā)(此處設置deep無意義)
//情況二:監(jiān)視ref所定義的多個響應式數據,寫成數組的形式
watch([sum,msg],(newValue,oldValue)=>{
console.log('sum或者msg變了',newValue,oldValue)
})
//情況三:監(jiān)視reactive所定義的響應式數據
//若監(jiān)視的是reactive定義的響應式數據,則無法正確獲得oldValue
//若監(jiān)視的是reactive定義的響應式數據,則watch會強制開啟深度監(jiān)視
//我們發(fā)現(xiàn)改變person的任意一個屬性都會被監(jiān)視到
watch(person,(newValue,oldValue)=>{
console.log('person改變了',newValue,oldValue)
})
//我們嘗試設置deep:false,關閉深度監(jiān)聽(目的:改變job的值不會被watch監(jiān)聽到)
//但是我們發(fā)現(xiàn)deep:false并沒有生效,原因是此時watch監(jiān)視的是reactive定義的響應式對象,默認強制開啟了深度監(jiān)聽
watch(person,(newValue,oldValue)=>{
console.log('person改變了',newValue,oldValue)
},{deep:false})
//情況四:監(jiān)視reactive所定義的響應式數據中的某個屬性
watch(()=>person.name,(newValue,oldValue)=>{
console.log('person的job改變了',newValue,oldValue)
})
watch(()=>person.age,(newValue,oldValue)=>{
console.log('person的job改變了',newValue,oldValue)
})
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job改變了',newValue,oldValue)
})
//從上邊我們發(fā)現(xiàn)改變name,age都會觸發(fā)監(jiān)聽,但是改變job不會
//這是因為name和age屬性的值只是一個簡單的基本類型數據,
//而job屬性的值是一個對象,比較深,想要監(jiān)視到,就要開啟深度監(jiān)視,程序如下:
watch(()=>person.job,(newValue,oldValue)=>{
console.log('person的job改變了',newValue,oldValue)
},{deep:true})//此時job改變,會被監(jiān)視到,此處的deep配置生效
//需要和情況三進行區(qū)分,此處watch監(jiān)視的是reactive所定義的對象中的某個屬性,而情況三watch監(jiān)視的是reactive所定義的對象
//情況五:監(jiān)視reactive所定義的響應式數據中的某些屬性,寫成數組的形式
watch([()=>person.name,()=>person.age],(newValue,oldValue)=>{
console.log('person的name或age改變了',newValue,oldValue)
})
//返回一個對象(常用)
return{
sum,
msg,
person
}
}
}
</script>watch取消監(jiān)聽
const stop1 = watch(
[() => nameObj.name, () => nameObj.name],
([curName, curEng], [prevName, curEng]) => {
console.log(curName, curEng, "----", prevName, curEng);
setTimeout(() => {
stop();
}, 5000);
}
);深度解析watchEffect函數
函數用法如下代碼所示,注釋詳細:
<template>
<div>
<h2>當前求和為:{{sum}}</h2>
<button @click="sum++">點我+1</button>
<hr>
<h2>當前的信息為:{{msg}} </h2>
<!-- 點擊button拼接! -->
<button @click="msg+='!'">修改數據</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年齡:{{person.age}}</h2>
<h2>薪資:{{person.job.j1.salary}}</h2>
<button @click="person.name+='~'"> 修改姓名</button>
<button @click="person.age++"> 增長年齡</button>
<button @click="person.job.j1.salary++"> 增長薪資</button>
</div>
</template>
<script>
import {ref,reactive,watch,watchEffect} from 'vue'
export default {
name:'demo',
setup(){
//數據
let sum = ref(0)
let msg = ref('hello')
let person = reactive({
name:'zhangsan',
age:'18',
job:{
j1:{
salary:20
}
}
})
//watchEffect函數內部所指定的回調中用到的數據只要發(fā)生變化,就會重新執(zhí)行回調
//只有一個參數,就是回調
watchEffect(()=>{
const x1 = sum.value//因為sum是ref定義的響應式數據,需要使用.value調用
const x2 = person.age
console.log('watchEffect配置的回調執(zhí)行了')
})
return{
sum,
msg,
person
}
}
}
</script>watchEffect取消監(jiān)聽
const stop = watchEffect(() => {
console.log(nameObj.name);
setTimeout(() => {
stop();
}, 5000);
});watchEffect與computed
watchEffect與computed有點像:
- 但是computed注重的計算出來的值(回調函數的返回值),所以必須要寫返回值。
- 而watchEffect更注重的是過程(回調函數的函數體),所以不用寫返回值。
- computed若是值沒有被使用時不會調用,但是watchEffect始終會調用一次
<template>
<div>
<h2>當前求和為:{{sum}}</h2>
<button @click="sum++">點我+1</button>
<hr>
<h2>當前的信息為:{{msg}} </h2>
<!-- 點擊button拼接! -->
<button @click="msg+='!'">修改數據</button>
<hr>
<h2>姓名:{{person.name}}</h2>
<h2>年齡:{{person.age}}</h2>
<h2>薪資:{{person.job.j1.salary}}</h2>
<button @click="person.name+='~'"> 修改姓名</button>
<button @click="person.age++"> 增長年齡</button>
<button @click="person.job.j1.salary++"> 增長薪資</button>
</div>
</template>
<script>
import {ref,reactive,watch,watchEffect, computed} from 'vue'
export default {
name:'demo',
setup(){
//數據
let sum = ref(0)
let msg = ref('hello')
let person = reactive({
name:'zhangsan',
age:'18',
job:{
j1:{
salary:20
}
}
})
let person1 = reactive({
firstName:'張',
lastName:'三'
})
//computed
//計算屬性——簡寫(沒有考慮計算屬性被修改的情況)
person1.fullName = computed(()=>{
//必須含有返回值
return person1.firstName+'-'+person1.lastName
})
//計算屬性——完整寫法(考慮讀和寫)
person1.fullName = computed({
//必須含有返回值
get(){
return person1.firstName+'-'+person1.lastName
},
set(value){
const nameArr = value.split('-')
person1.firstName = nameArr[0]
person1.lastName = nameArr[1]
}
})
//watchEffect
//可以不寫給返回值
watchEffect(()=>{
const x1 = sum.value//因為sum是ref定義的響應式數據,需要使用.value調用
const x2 = person.age
console.log('watchEffect配置的回調執(zhí)行了')
})
return{
sum,
msg,
person,
person1
}
}
}
</script>到此這篇關于Vue中watch與watchEffect的區(qū)別詳細解讀的文章就介紹到這了,更多相關watch與watchEffect的區(qū)別內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
基于Vue實現(xiàn)圖片在指定區(qū)域內移動的思路詳解
這篇文章主要介紹了基于Vue實現(xiàn)圖片在指定區(qū)域內移動,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11
vue項目實現(xiàn)表單登錄頁保存賬號和密碼到cookie功能
這篇文章主要介紹了vue項目實現(xiàn)表單登錄頁保存賬號和密碼到cookie功能,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-08-08

