Vue 3 中使用路由參數(shù)跳轉(zhuǎn)時(shí) watch 觸發(fā)重復(fù)請(qǐng)求問(wèn)題解決
??Vue 3 中使用路由參數(shù)跳轉(zhuǎn)時(shí) watch 觸發(fā)重復(fù)請(qǐng)求問(wèn)題詳解
掌握 Vue 3 路由參數(shù)監(jiān)聽(tīng)中的隱藏陷阱,避免詳情頁(yè)、嵌套路由頁(yè)誤觸發(fā)重復(fù)請(qǐng)求!
?? 一、問(wèn)題背景
在 Vue 3 項(xiàng)目中,常見(jiàn)需求是:
- 在列表頁(yè)點(diǎn)擊跳轉(zhuǎn)到詳情頁(yè),傳遞
id參數(shù) - 詳情頁(yè)通過(guò)
watch(() => route.query.id)監(jiān)聽(tīng)路由變化,自動(dòng)請(qǐng)求數(shù)據(jù)
例如:
watch(() => route.query.id, (newId) => {
fetchDetail(newId)
})?? 看似合理,但如果你在詳情頁(yè)內(nèi)點(diǎn)擊跳轉(zhuǎn)其他頁(yè)面(如訂單詳情頁(yè)),此 watch 也會(huì)執(zhí)行,可能導(dǎo)致:
- ? 重復(fù)發(fā)起請(qǐng)求
- ? 未更新界面但數(shù)據(jù)已重新加載
- ? 性能浪費(fèi)與閃爍問(wèn)題
?? 二、問(wèn)題演示
示例場(chǎng)景:
- 當(dāng)前在
/performance/detail?id=1001 - 頁(yè)面中點(diǎn)擊跳轉(zhuǎn)訂單詳情頁(yè)
/order/detail?id=123456 - 此時(shí)路由
query.id發(fā)生變化,watch(() => route.query.id)被觸發(fā) - 結(jié)果是:
getList()又執(zhí)行了一次
?問(wèn)題本質(zhì):
watch(() => route.query.id, (newId) => {
getList() // 此時(shí)其實(shí)已跳轉(zhuǎn)出當(dāng)前詳情頁(yè)了!
})? 三、正確解決方案
? 核心思路:監(jiān)聽(tīng)時(shí)加“當(dāng)前頁(yè)面判斷”
watch(() => route.query.id, (newId) => {
if (route.name !== 'PerformanceDetail') return // ?? 頁(yè)面已跳轉(zhuǎn),不處理
if (newId && newId !== userId.value) {
userId.value = newId
queryParams.value.userId = newId
getList() // ? 安全觸發(fā)
}
})?? 四、配合路由 name 使用
你需要在路由配置中設(shè)置 name:
{
path: '/performance/detail',
name: 'PerformanceDetail',
component: () => import('@/views/PerformanceDetail.vue')
}路由中使用 route.name 是判斷是否仍在當(dāng)前頁(yè)面的推薦方式。
?? 五、完整封裝模板(推薦復(fù)制使用)
import { watch } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
watch(() => route.query.id, (newId) => {
if (route.name !== 'YourPageName') return // 避免跳出當(dāng)前頁(yè)還觸發(fā)請(qǐng)求
if (!newId || newId === currentId.value) return
currentId.value = newId
fetchData(newId)
})?? 六、進(jìn)階封裝建議:自定義 Hook
你還可以封裝為通用函數(shù):
function useQueryParamWatcher(key, callback, routeName) {
const route = useRoute()
watch(() => route.query[key], (val) => {
if (route.name !== routeName) return
callback(val)
}, { immediate: true })
}使用:
useQueryParamWatcher('id', fetchData, 'PerformanceDetail')? 七、總結(jié)建議
| 場(chǎng)景 | 是否觸發(fā) watch |
|---|---|
| 當(dāng)前詳情頁(yè)中更換 id | ? 應(yīng)觸發(fā) |
| 從詳情頁(yè)跳轉(zhuǎn)訂單頁(yè) | ? 不應(yīng)觸發(fā) |
| 瀏覽器返回回到詳情頁(yè) | ? 應(yīng)觸發(fā) |
| 從其他模塊進(jìn)入此頁(yè) | ? 應(yīng)觸發(fā) |
?? 不判斷路由名稱,watch 很容易被“跨頁(yè)參數(shù)變動(dòng)”誤觸發(fā)!
?? 八、知識(shí)點(diǎn)補(bǔ)充
route.query.id是響應(yīng)式的,變化即觸發(fā)watch- Vue Router 的 query 和 params 都是響應(yīng)式
- 路由跳轉(zhuǎn)過(guò)程中,setup 并不會(huì)重新執(zhí)行,watch 需要手動(dòng)判斷上下文
?? 結(jié)語(yǔ)
通過(guò)本文你應(yīng)掌握:
? 為什么 watch(route.query.id) 會(huì)重復(fù)觸發(fā)
? 如何判斷是否仍在當(dāng)前頁(yè)面
? 如何使用 route.name 做頁(yè)面隔離
? 如何避免離開(kāi)時(shí)誤請(qǐng)求、重復(fù)請(qǐng)求
到此這篇關(guān)于Vue 3 中使用路由參數(shù)跳轉(zhuǎn)時(shí) watch 觸發(fā)重復(fù)請(qǐng)求問(wèn)題解決的文章就介紹到這了,更多相關(guān)vue watch 觸發(fā)重復(fù)請(qǐng)求內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- vue?禁止重復(fù)點(diǎn)擊發(fā)送多次請(qǐng)求的實(shí)現(xiàn)
- Vue axios庫(kù)避免重復(fù)發(fā)送請(qǐng)求的示例介紹
- vue阻止重復(fù)請(qǐng)求實(shí)現(xiàn)示例詳解
- Vue路由切換和Axios接口取消重復(fù)請(qǐng)求詳解
- Vue中Axios中取消請(qǐng)求及阻止重復(fù)請(qǐng)求的方法
- vue axios攔截器常用之重復(fù)請(qǐng)求取消
- vue axios重復(fù)點(diǎn)擊取消上一次請(qǐng)求封裝的方法
- Vue3 + vue-query 的重復(fù)請(qǐng)求問(wèn)題解決
相關(guān)文章
vue?elementui?大文件進(jìn)度條下載功能實(shí)現(xiàn)
本文介紹了如何使用下載進(jìn)度條來(lái)展示下載進(jìn)度的方法,并展示了相關(guān)的效果圖,結(jié)合實(shí)例代碼介紹了vue?elementui?大文件進(jìn)度條下載的方法,感興趣的朋友一起看看吧2025-01-01
vue2如何使用simple-keyboard軟鍵盤有中文(拼音)
這篇文章主要介紹了vue2如何使用simple-keyboard軟鍵盤有中文(拼音),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-04-04
vue+Element-ui前端實(shí)現(xiàn)分頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了vue+Element-ui前端實(shí)現(xiàn)分頁(yè)效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
使用vue腳手架(vue-cli)搭建一個(gè)項(xiàng)目詳解
這篇文章主要介紹了vue腳手架(vue-cli)搭建項(xiàng)目,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Vue插件報(bào)錯(cuò):Vue.js is detected on this page.問(wèn)題解決
這篇文章主要介紹了Vue插件報(bào)錯(cuò):Vue.js is detected on this page.問(wèn)題解決,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
vue+element實(shí)現(xiàn)手機(jī)號(hào)驗(yàn)證碼注冊(cè)的示例
本文主要介紹了vue+element實(shí)現(xiàn)手機(jī)號(hào)驗(yàn)證碼注冊(cè)的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
Vue整合Node.js直連Mysql數(shù)據(jù)庫(kù)進(jìn)行CURD操作過(guò)程詳解
這篇文章主要給大家分享Vue整合Node.js,直連Mysql數(shù)據(jù)庫(kù)進(jìn)行CURD操作的詳細(xì)過(guò)程,文中有詳細(xì)的代碼講解,具有一定的參考價(jià)值,需要的朋友可以參考下2023-07-07
Elementui按鈕設(shè)置默認(rèn)選中狀態(tài)的實(shí)現(xiàn)過(guò)程
這篇文章主要給大家介紹了關(guān)于Elementui按鈕設(shè)置默認(rèn)選中狀態(tài)的實(shí)現(xiàn)過(guò)程,文中通過(guò)圖文以及示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Elementui具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2023-07-07

