Vue中watch使用方法詳解
前言
說到 vue 中的 watch 方法,大家可能首先想到,它是用來監(jiān)聽數(shù)據(jù)的變化,一旦數(shù)據(jù)發(fā)生變化可以執(zhí)行一些其他的操作。但是 watch 的操作可不止如此,本章就帶大家一起深剖細析 vue 中的 watch 方法。
watch
因為 vue 是雙向數(shù)據(jù)綁定,所以當(dāng)頁面數(shù)據(jù)發(fā)生變化時,我們通過 watch 方法就可以拿到數(shù)據(jù)變化前和變化后的值,從而做一系列操作,下面我們通過一個簡單的例子來解釋。
先看下面這段代碼
<template>
<div>
<input type="text" v-model="nameModel" />
</div>
</template>
<script>
export default {
data() {
return {
nameModel: "",
};
},
watch: {
nameModel() {
console.log("觸發(fā)打印");
},
},
};
</script>
實現(xiàn)效果

immediate和handler
問:immediate 和 handler 是干嘛用的?
在回答這個問題之前,我們先回到上面的例子中,如果我想讓值第一次綁定的時候就監(jiān)聽函數(shù)該怎么辦?這就牽扯到 watch 的一個特點,就是當(dāng)值第一次綁定的時候,不會執(zhí)行監(jiān)聽函數(shù),只有值發(fā)生改變才會執(zhí)行。那如果我們就是需要在最初綁定值的時候也執(zhí)行函數(shù),舉個最常見的例子,當(dāng)父組件向子組件動態(tài)傳值時,子組件 props 首次接收父組件傳來的默認(rèn)值時,也需要執(zhí)行函數(shù),這個時候就需要用到 immediate 屬性。
接著看下面這段代碼
父組件
<template>
<div>
<Child :message="informtion"></Child>
</div>
</template>
<script>
import Child from "./subassembly/seed.vue";
export default {
data() {
return {
informtion: "默認(rèn)傳遞給子組件的數(shù)據(jù)",
};
},
components: {
Child,
},
};
</script>
子組件
<template>
<h2>接收父組件值:{{ value }}</h2>
</template>
<script>
export default {
data() {
return {
value: "",
};
},
props: {
message: {
type: String,
default: "",
},
},
watch: {
message: {
handler(newName, oldName) {
this.value = newName;
},
immediate: true, //首次綁定的時候,是否執(zhí)行 handler
},
},
};
</script>
當(dāng) immediate 為 false 時

當(dāng) immediate 為 true 時

通過上面的例子我們不難推出:immediate 表示在 watch 中首次綁定的時候,是否執(zhí)行 handler,值為 true 時表示在 watch 中聲明的時候,就立即執(zhí)行 handler 方法,反之,則和一般使用 watch 一樣,在數(shù)據(jù)發(fā)生變化的時候才執(zhí)行 handler。
注意:handler 有 2 個參數(shù)。第一個是 newValue,第二個是 oldValue,分別表示新的值和舊的值。
deep
deep 其實就是深度監(jiān)聽,那可能又有同學(xué)要問了,深度監(jiān)聽又是啥?試想一下,當(dāng)你監(jiān)聽的目標(biāo)是一個對象時,當(dāng)對象中的 a 值發(fā)生變化,在不使用 deep 的前提下,是不會觸發(fā) handler 函數(shù)的,因為這個對象并沒有改變,再通俗的講就是對象中的 a 并沒有變成 b 或者是消失了,你只是修改了 a 的值,但是 a 的值是 a 的,并不是對象的,并不能代表對象的改變。
再看下面這段代碼
<template>
<div>
<input type="text" v-model="forms.nameModel" />
</div>
</template>
<script>
export default {
data() {
return {
forms: {
nameModel: "",
},
};
},
watch: {
forms: {
handler(newName, oldName) {
console.log("觸發(fā)打印");
},
},
},
};
</script>
實現(xiàn)效果

可以看到控制臺并沒有打印任何結(jié)果,再回到上面的問題,deep 屬性就是用來解決這個問題的。當(dāng)你需要監(jiān)聽一個對象的改變時,普通的 watch 方法無法監(jiān)聽到對象內(nèi)部屬性的改變,只有 data 中的數(shù)據(jù)才能夠監(jiān)聽到變化,此時就需要 deep 屬性對對象進行深度監(jiān)聽。
正確的寫法
通過設(shè)置 deep: true 則可以監(jiān)聽到對象中屬性值的變化。
<template>
<div>
<input type="text" v-model="forms.nameModel" />
</div>
</template>
<script>
export default {
data() {
return {
forms: {
nameModel: "",
},
};
},
watch: {
forms: {
handler(newName, oldName) {
console.log("觸發(fā)打印");
},
deep: true,
},
},
};
</script>
實現(xiàn)效果

有同學(xué)可能要問了,對象中有 n 個屬性,但是我只想監(jiān)聽某一個屬性值的變化該怎么寫呢?其實有一個非常簡單的方法:使用字符串的形式監(jiān)聽對象屬性值變化。
實例
<template>
<div>
<input type="text" v-model="forms.nameModel" />
</div>
</template>
<script>
export default {
data() {
return {
forms: {
nameModel: "",
},
};
},
watch: {
"forms.nameModel": {
handler(newName, oldName) {
console.log("觸發(fā)打印");
},
},
},
};
</script>
實現(xiàn)效果

注意: 數(shù)組(一維、多維)的變化不需要通過深度監(jiān)聽,對象數(shù)組中對象的屬性變化則需要深度監(jiān)聽。
拓展
computed 和 watch 區(qū)別
兩者最明顯的區(qū)別在于 watch 是觀察某一個屬性的變化,從而重新計算屬性的值;而 computed 是通過所依賴的屬性的變化計算屬性值,在絕大部分情況下,computed 和 watch 沒有明顯區(qū)別,但如果是在數(shù)據(jù)變化的同時進行異步操作,那么 watch 無疑是最好的選擇。
到此這篇關(guān)于Vue中watch使用方法詳解的文章就介紹到這了,更多相關(guān)Vue watch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
echarts3如何清空上一次加載的series數(shù)據(jù)
這篇文章主要介紹了echarts3如何清空上一次加載的series數(shù)據(jù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
Vue是怎么渲染template內(nèi)的標(biāo)簽內(nèi)容的
這篇文章主要介紹了Vue是怎么渲染template內(nèi)的標(biāo)簽內(nèi)容的,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06
Vue Router的手寫實現(xiàn)方法實現(xiàn)
這篇文章主要介紹了Vue Router的手寫實現(xiàn)方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03

