閱讀優(yōu)秀的文章
詳解Vue中的computed和watch
vue中computed、watch、methods與生命周期的執(zhí)行順序
Vue中的watch又名為偵聽屬性,它主要用于偵聽數(shù)據(jù)的變化,在數(shù)據(jù)發(fā)生變化的時候執(zhí)行一些操作。
Vue官網(wǎng)很明確的建議我們這樣使用watch偵聽屬性:當(dāng)需要在數(shù)據(jù)變化時執(zhí)行異步或開銷較大的操作時,這個方式是最有用的。
watch的用法
直接寫一個監(jiān)聽處理函數(shù),當(dāng)每次監(jiān)聽到cityName值發(fā)生改變時,執(zhí)行函數(shù)。
<template>
<div id="app">
<p>計數(shù)器:{{counter}}</p>
<el-button type="primary" @click="counter++">
Click
</el-button>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
counter: 0
}
},
watch: {
/**
* @name: counter
* @description:
* 監(jiān)聽Vue data中的counter數(shù)據(jù)
* 當(dāng)counter發(fā)生變化時會執(zhí)行對應(yīng)的偵聽函數(shù)
* @param {*} newValue counter的新值
* @param {*} oldValue counter的舊值
* @return {*} None
*/
counter(newValue, oldValue){
if(this.counter == 10){
this.counter = 0;
}
}
}
}
</script>
handler
那上面的這種寫法等同于給counter提供一個handler函數(shù):
watch: {
counter: {
handler(newValue, oldValue){
if(this.counter == 10){
this.counter = 0;
}
}
}
}
immediate
正常情況下,偵聽屬性提供的函數(shù)是不會立即執(zhí)行的,只有在對應(yīng)的vue data發(fā)生變化時,偵聽屬性對應(yīng)的函數(shù)才會執(zhí)行。
那如果我們需要偵聽屬性對應(yīng)的函數(shù)立即執(zhí)行一次,就可以給偵聽屬性提供一個immediate選項,并設(shè)置其值為true。
使用場景:
比如當(dāng)父組件向子組件動態(tài)傳值時,子組件props首次獲取到父組件傳來得默認(rèn)值時,也需要執(zhí)行函數(shù),此時就需要將immediate設(shè)為true。
- immediate:true 會導(dǎo)致一個問題
immediate會讓watch執(zhí)行順序提升至created之前,這個可是坑點,如果你在immediate中修改了初始data值,就會導(dǎo)致created獲取的值是修改過的值,導(dǎo)致一些人瞬間懵逼。
watch: {
counter: {
handler(newValue, oldValue){
if(this.counter == 10){
this.counter = 0;
}
},
immediate: true
}
}
deep
如果我們對一個對象類型的vue data進(jìn)行偵聽,當(dāng)這個對象內(nèi)的屬性發(fā)生變化時,默認(rèn)是不會觸發(fā)偵聽函數(shù)的
<template>
<div id="app">
<p><el-input v-model="person.name" placeholder="請輸入姓名"></el-input></p>
<p><el-input v-model="person.age" placeholder="請輸入年齡"></el-input></p>
</div>
</template>
<script>
export default {
name: 'App',
data() {
return {
person: {
name: 'jack',
age: 20
}
}
},
watch: {
person: function(newValue){
console.log(newValue.name + ' ' + newValue.age);
}
}
}
</script>
注意問題
- 在watch中不要使用箭頭函數(shù),即不應(yīng)該使用箭頭函數(shù)來定義 watcher 函數(shù) , 因為箭頭函數(shù)中的this是指向當(dāng)前作用域。
對于箭頭函數(shù)來說,箭頭函數(shù)中的 this 指向的是定義時的對象而不是函數(shù)運行時所在的對象,即全局定義時的windows對象。
--記錄問題
我在父組件定義了一個對象空對象,請求后給對象賦值
sourceParamsObj: {} // data里定義了空的對象
this.sourceParamsObj.fileId = 1
然后props到子組件后,通過watch監(jiān)聽sourceParamsObj對象,deep為true也一直監(jiān)聽不到。
后來發(fā)現(xiàn)是因為sourceParamsObj定義了空對象,要在初始值時就給對象屬性
sourceParamsObj: { fileId: '' }
這樣就能監(jiān)聽到了。
關(guān)于這個問題的解釋:https://blog.csdn.net/qq_41221596/article/details/128505767