Vue中watch使用方法詳解
前言
說到 vue 中的 watch 方法,大家可能首先想到,它是用來監(jiān)聽數(shù)據(jù)的變化,一旦數(shù)據(jù)發(fā)生變化可以執(zhí)行一些其他的操作。但是 watch 的操作可不止如此,本章就帶大家一起深剖細(xì)析 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
屬性對對象進(jìn)行深度監(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ù)變化的同時進(jìn)行異步操作,那么 watch
無疑是最好的選擇。
到此這篇關(guān)于Vue中watch使用方法詳解的文章就介紹到這了,更多相關(guān)Vue watch內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue中Router路由兩種模式hash與history詳解
這篇文章主要介紹了Vue中Router路由的兩種模式,分別對hash模式與history模式作了簡要分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09vuecli+AXdownload下載組件封裝?+css3下載懸浮球動畫效果
當(dāng)觸發(fā)下載功能的時候,會觸發(fā)一個下載動畫,下載懸浮球會自動彈出,并且閃爍提示有新的下載任務(wù)直到下載任務(wù)完場提示,接下來通過本文介紹vuecli+AXdownload下載組件封裝?+css3下載懸浮球動畫效果,需要的朋友可以參考下2024-05-05