一文教你vue3 watch如何停止監(jiān)視
如何停止監(jiān)聽(tīng)呢?
下面分兩種情況進(jìn)行講解
情況一
情況一是使用回調(diào)函數(shù),停止事件監(jiān)聽(tīng)
<!-- 這個(gè)界面就是花上的葉子,要在App中引入,把葉子裝在枝干上 -->
<template>
<div class="person">
<h1>【情況一:監(jiān)視r(shí)ef定義的基本類(lèi)型數(shù)據(jù)】</h1>
<h2 @click="changeSum">當(dāng)前求和為:{{ sum }}</h2>
</div>
</template>
<script lang="ts" setup name="Person">
// 導(dǎo)入
import { ref, watch } from 'vue'
// 數(shù)據(jù)
let sum = ref(0)
// 方法
function changeSum() {
sum.value++
}
// 監(jiān)視
const stopWatch = watch(sum, (newValue, oldValue) => {
console.log(`sum的值發(fā)生了改變, 新:${newValue},舊值:${oldValue}`)
if(newValue > 5) {
stopWatch()
}
})
console.log(stopWatch)
//可以看看打印的結(jié)果,運(yùn)行界面之后按F12,打開(kāi)控制臺(tái)可進(jìn)行查看
//
</script>
<style scoped>
.person {
background-color: skyblue;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
border-radius: 10px;
padding: 20px;
}
</style>內(nèi)容講解
上面給sum值添加了一個(gè)監(jiān)聽(tīng),那如何停止監(jiān)聽(tīng)呢?
就是給watch執(zhí)行了一個(gè)回調(diào)函數(shù)
在這個(gè)代碼中,開(kāi)始時(shí) watch 對(duì) count 進(jìn)行監(jiān)聽(tīng),每次 count 的值改變,回調(diào)函數(shù)就會(huì)執(zhí)行并打印變化信息。但當(dāng) count 的值達(dá)到 5 或者更大時(shí),stopWatch 函數(shù)被調(diào)用,此時(shí) Vue 內(nèi)部會(huì)依據(jù)這個(gè)調(diào)用執(zhí)行相應(yīng)的清理工作,解除對(duì) count 后續(xù)變化的監(jiān)聽(tīng)關(guān)系,之后哪怕 count 的值再怎么改變,也不會(huì)執(zhí)行這個(gè) watch 對(duì)應(yīng)的回調(diào)函數(shù)了,實(shí)現(xiàn)了停止監(jiān)聽(tīng)的目的。
所以,stopWatch 函數(shù)本質(zhì)上是 Vue 提供的用于手動(dòng)控制 watch 監(jiān)聽(tīng)生命周期的一個(gè)工具,方便開(kāi)發(fā)者根據(jù)業(yè)務(wù)邏輯需求靈活決定何時(shí)停止對(duì)特定數(shù)據(jù)變化的關(guān)注和響應(yīng)
內(nèi)部實(shí)現(xiàn)機(jī)制
watch 函數(shù)內(nèi)部其實(shí)維護(hù)了一套用于觀察和響應(yīng)數(shù)據(jù)變化的邏輯,它會(huì)在你傳入要監(jiān)聽(tīng)的數(shù)據(jù)(比如 ref 定義的響應(yīng)式數(shù)據(jù)或者 reactive 定義的響應(yīng)式對(duì)象等)后,通過(guò) Vue 的響應(yīng)式系統(tǒng)來(lái)追蹤這些數(shù)據(jù)的變化情況。當(dāng)數(shù)據(jù)發(fā)生變化時(shí),就會(huì)觸發(fā)對(duì)應(yīng)的回調(diào)函數(shù)執(zhí)行相應(yīng)的操作。
而返回的這個(gè) stopWatch 函數(shù),實(shí)際上是一個(gè)關(guān)閉這個(gè)特定監(jiān)聽(tīng)任務(wù)的接口。當(dāng) watch 開(kāi)始監(jiān)聽(tīng)時(shí),它會(huì)創(chuàng)建一個(gè)內(nèi)部的訂閱者對(duì)象或者類(lèi)似的結(jié)構(gòu)(具體是內(nèi)部的實(shí)現(xiàn)細(xì)節(jié),但可以簡(jiǎn)單這么理解)來(lái)負(fù)責(zé)檢測(cè)數(shù)據(jù)變化并觸發(fā)回調(diào)。這個(gè) stopWatch 函數(shù)被調(diào)用時(shí),它會(huì)在內(nèi)部執(zhí)行一些清理操作,比如移除與這個(gè)監(jiān)聽(tīng)相關(guān)的事件訂閱、取消對(duì)數(shù)據(jù)變化的追蹤關(guān)聯(lián)等,從而使得后續(xù)這個(gè)被監(jiān)聽(tīng)的數(shù)據(jù)即便再發(fā)生變化,也不會(huì)再觸發(fā)對(duì)應(yīng)的回調(diào)函數(shù)了,也就是實(shí)現(xiàn)了停止監(jiān)聽(tīng)的效果。
類(lèi)比理解
可以把 watch 的監(jiān)聽(tīng)過(guò)程想象成你訂閱了一份報(bào)紙(數(shù)據(jù)變化就是有新的消息更新),每天送報(bào)員(Vue 的響應(yīng)式系統(tǒng))會(huì)查看報(bào)紙有沒(méi)有新內(nèi)容(數(shù)據(jù)有沒(méi)有變化),如果有就會(huì)給你送過(guò)來(lái)(觸發(fā)回調(diào)函數(shù))。而 stopWatch 函數(shù)就好比你打電話(huà)給報(bào)社說(shuō) “我不想再訂閱了”(調(diào)用 stopWatch),報(bào)社接到通知后(內(nèi)部進(jìn)行清理操作),就不會(huì)再安排送報(bào)員給你送報(bào)紙了(不再追蹤數(shù)據(jù)變化觸發(fā)回調(diào)),你也就不會(huì)再接收到后續(xù)的報(bào)紙(不會(huì)再響應(yīng)數(shù)據(jù)變化了)。
情況二
情況二是調(diào)用函數(shù)進(jìn)行暫停,恢復(fù)和停止時(shí)間監(jiān)聽(tīng)
<template>
<div class="Test">
<h1>Watch示例 - 暫停、恢復(fù)與停止監(jiān)聽(tīng)演示</h1>
<p>當(dāng)前計(jì)數(shù): {{ count }}</p>
<button @click="increment">增加計(jì)數(shù)</button>
<button @click="decrement">減少計(jì)數(shù)</button>
<button @click="pauseWatch">暫停監(jiān)聽(tīng)</button>
<button @click="resumeWatch">恢復(fù)監(jiān)聽(tīng)</button>
<button @click="stopWatch">停止監(jiān)聽(tīng)</button>
</div>
</template>
<script setup>
import { ref, watch } from 'vue';
// 創(chuàng)建響應(yīng)式數(shù)據(jù),用于存儲(chǔ)計(jì)數(shù)器的值,初始值為0
const count = ref(0);
// 用于存儲(chǔ)watch實(shí)例,后續(xù)通過(guò)它來(lái)調(diào)用pause、resume、stop方法
let watchInstance;
// 定義watch監(jiān)聽(tīng)計(jì)數(shù)變化,當(dāng)計(jì)數(shù)變化時(shí)打印相關(guān)信息
watchInstance = watch(count, (newValue, oldValue) => {
console.log(`計(jì)數(shù)從 ${oldValue} 變?yōu)?${newValue}`);
});
// 增加計(jì)數(shù)的方法
const increment = () => {
count.value++;
};
// 減少計(jì)數(shù)的方法
const decrement = () => {
count.value--;
};
// 暫停監(jiān)聽(tīng)的方法
const pauseWatch = () => {
watchInstance.pause();
console.log('已暫停對(duì)計(jì)數(shù)變化的監(jiān)聽(tīng)');
};
// 恢復(fù)監(jiān)聽(tīng)的方法
const resumeWatch = () => {
watchInstance.resume();
console.log('已恢復(fù)對(duì)計(jì)數(shù)變化的監(jiān)聽(tīng)');
};
// 停止監(jiān)聽(tīng)的方法
const stopWatch = () => {
watchInstance.stop();
console.log('已停止對(duì)計(jì)數(shù)變化的監(jiān)聽(tīng),后續(xù)計(jì)數(shù)變化將不再觸發(fā)監(jiān)聽(tīng)回調(diào)');
};
</script>
<style scoped>
.Test {
text-align: center;
padding: 20px;
background-color: #faebeb;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
button {
margin: 5px 10px;
padding: 8px 15px;
border: none;
border-radius: 5px;
background-color: #007bff;
color: white;
cursor: pointer;
}
</style>模板部分(<template>)
展示了一個(gè)簡(jiǎn)單的頁(yè)面結(jié)構(gòu),包含顯示當(dāng)前計(jì)數(shù)的文本、用于增加計(jì)數(shù)和減少計(jì)數(shù)的按鈕,以及分別對(duì)應(yīng)暫停監(jiān)聽(tīng)、恢復(fù)監(jiān)聽(tīng)和停止監(jiān)聽(tīng)的按鈕,方便用戶(hù)操作并觀察不同操作對(duì)監(jiān)聽(tīng)的影響。
腳本部分(<script setup>)
響應(yīng)式數(shù)據(jù)與watch監(jiān)聽(tīng)初始化:
通過(guò) ref 創(chuàng)建了 count 這個(gè)響應(yīng)式數(shù)據(jù),初始值設(shè)為 0,用于模擬計(jì)數(shù)器的值。
使用 watch 監(jiān)聽(tīng) count 的變化,每當(dāng) count 的值發(fā)生改變,回調(diào)函數(shù)就會(huì)執(zhí)行并在控制臺(tái)打印出計(jì)數(shù)變化的前后值,如 計(jì)數(shù)從 1 變?yōu)?2 這樣的信息,同時(shí)將 watch 實(shí)例賦值給 watchInstance 變量,以便后續(xù)調(diào)用其相關(guān)方法。
操作計(jì)數(shù)的方法:
分別定義了 increment 和 decrement 方法,用于增加和減少 count 的值,通過(guò)點(diǎn)擊頁(yè)面上對(duì)應(yīng)的按鈕可以改變 count 的值,從而觸發(fā) watch 的監(jiān)聽(tīng)回調(diào)(在未暫停、停止監(jiān)聽(tīng)的情況下)。
暫停、恢復(fù)和停止監(jiān)聽(tīng)的方法:
pauseWatch 方法:調(diào)用 watchInstance.pause() 來(lái)暫停對(duì) count 變化的監(jiān)聽(tīng),并且在控制臺(tái)打印提示信息告知用戶(hù)已暫停監(jiān)聽(tīng),此后再改變 count 的值,watch 的回調(diào)函數(shù)不會(huì)被觸發(fā)執(zhí)行,直到調(diào)用 resumeWatch 方法恢復(fù)監(jiān)聽(tīng)。
resumeWatch 方法:調(diào)用 watchInstance.resume() 來(lái)恢復(fù)之前被暫停的對(duì) count 變化的監(jiān)聽(tīng),同時(shí)在控制臺(tái)打印相應(yīng)提示信息,恢復(fù)后,若 count 的值再次改變,watch 的回調(diào)函數(shù)又會(huì)正常執(zhí)行了。
stopWatch 方法:調(diào)用 watchInstance.stop() 徹底停止對(duì) count 變化的監(jiān)聽(tīng),打印提示信息說(shuō)明后續(xù)計(jì)數(shù)變化將不再觸發(fā)監(jiān)聽(tīng)回調(diào),意味著之后無(wú)論怎么改變 count 的值,watch 對(duì)應(yīng)的回調(diào)函數(shù)都不會(huì)再執(zhí)行了,監(jiān)聽(tīng)關(guān)系被完全解除。
這個(gè)就是console.log()的watchStop

到此這篇關(guān)于一文教你vue3 watch如何停止監(jiān)視的文章就介紹到這了,更多相關(guān)vue3 watch停止監(jiān)視內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue.js 點(diǎn)擊按鈕顯示/隱藏內(nèi)容的實(shí)例代碼
下面小編就為大家分享一篇Vue.js 點(diǎn)擊按鈕顯示/隱藏內(nèi)容的實(shí)例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
vue 登錄滑動(dòng)驗(yàn)證實(shí)現(xiàn)代碼
這篇文章主要介紹了vue 登錄滑動(dòng)驗(yàn)證實(shí)現(xiàn)代碼,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-08-08
在vue中使用echarts實(shí)現(xiàn)上浮與下鉆效果
這篇文章主要介紹了在vue中使用echarts實(shí)現(xiàn)上浮與下鉆效果,本文分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
vue router-link傳參以及參數(shù)的使用實(shí)例
下面小編就為大家?guī)?lái)一篇vue router-link傳參以及參數(shù)的使用實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11
vue使用Element-UI部分組件適配移動(dòng)端問(wèn)題
這篇文章主要介紹了vue使用Element-UI部分組件適配移動(dòng)端問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-03-03
vue element-ui table組件動(dòng)態(tài)生成表頭和數(shù)據(jù)并修改單元格格式 父子組件通信
這篇文章主要介紹了vue element-ui table組件動(dòng)態(tài)生成表頭和數(shù)據(jù)并修改單元格格式 父子組件通信,需要的朋友可以參考下2019-08-08
vue項(xiàng)目總結(jié)之文件夾結(jié)構(gòu)配置詳解
這篇文章主要給大家總結(jié)介紹了關(guān)于vue項(xiàng)目之文件夾結(jié)構(gòu)配置的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12
vue使用高德地圖實(shí)現(xiàn)實(shí)時(shí)定位天氣預(yù)報(bào)功能
這篇文章主要介紹了vue使用高德地圖實(shí)現(xiàn)實(shí)時(shí)天氣預(yù)報(bào)功能,根據(jù)定位功能,使用高德地圖實(shí)現(xiàn)定位當(dāng)前城市的天氣預(yù)報(bào)功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05

