vue3不能使用history.pushState修改url參數(shù)踩坑
前言
在重構(gòu)我的 vue-use-sync-url(輔助將數(shù)據(jù)和 url 參數(shù)進(jìn)行同步的工具庫(kù))時(shí),遇到了一個(gè)使用 window.history.pushState
來(lái)修改地址欄的 url 參數(shù)的 bug,準(zhǔn)確來(lái)說(shuō)是 vue-router
的 bug,下面就來(lái)講講具體是怎么回事。
問(wèn)題
場(chǎng)景如下,有一個(gè)輸入框里面輸入了內(nèi)容,點(diǎn)擊搜索按鈕使用 window.history.pushState
將數(shù)據(jù)同步到 url 參數(shù)上。然后再點(diǎn)擊 go about
按鈕跳轉(zhuǎn)到別的頁(yè)面,關(guān)鍵的來(lái)了,這時(shí)候你點(diǎn)擊瀏覽器左上角的回退按鈕回到剛才的頁(yè)面,url 上的 keywords
參數(shù)變沒(méi)了! 這里上個(gè)測(cè)試鏈接 codesandbox
<script setup> import { ref } from "vue"; const keywords = ref("123") const handleClick = () => { window.history.pushState({}, "", `${window.location.pathname}?keywords=${keywords.value}`) } </script> <template> <input v-model="keywords" /> <button @click="handleClick">搜索</button> <router-link to="/about">go about</router-link> </template>
追根溯源
一開(kāi)始想是不是我寫(xiě)的有問(wèn)題?測(cè)試了 vue2-router
和 react-router
都沒(méi)有這個(gè)問(wèn)題,所以我就將問(wèn)題鎖定在了 vue3-router
了。因?yàn)?router-link
和直接執(zhí)行了 router.push
操作是一樣的,所以我就去找 push
操作所在的源碼位置,最終在 packages/router/src/history/html5.ts
中找到了如下代碼。
可以看到在這個(gè) push
函數(shù)中,在第 288 行,執(zhí)行了一次 replace
的操作,而在第 297 行才是真正的 push
操作。我將第 288 行注釋之后,上面的 demo 就跑通了,但是直覺(jué)告訴我它這里這么做是有原因的,但是想弄明白估計(jì)得將整個(gè)庫(kù)的源碼看完,沒(méi)有這個(gè)精力。直接提了個(gè) issue,在它的 github issue 中我發(fā)現(xiàn)了好幾個(gè)由于這個(gè)第 288 行代碼產(chǎn)生的問(wèn)題,例如 #1416、#1526、#1529。維護(hù)者在我的 issue 中是這么回答的。
結(jié)合他在其它 issue 中的回答,大概是如下這么個(gè)意思。直接使用 history
api,路由器是不知道的,應(yīng)該避免使用,最好使用 router.push
來(lái)進(jìn)行更改。還說(shuō)到第 288 行對(duì)于更新當(dāng)前歷史記錄條目是必要的,以便能夠通過(guò)導(dǎo)航守衛(wèi)取消ui 發(fā)起的導(dǎo)航。它允許知道導(dǎo)航的方向和在歷史堆棧中的相對(duì)位置。不幸的是,目前還沒(méi)有其他方法可以做到這一點(diǎn)。
我補(bǔ)充道,在 vue2
和 react
中沒(méi)有這個(gè)問(wèn)題,你不覺(jué)得這是個(gè) bug
嗎?他說(shuō)在 vue2
中使用 hisotry
api 可能會(huì)產(chǎn)生你沒(méi)有遇到過(guò)的問(wèn)題,vue-router
在 vue3
中比 vue2
擁有更多的功能等等。
解決
沒(méi)辦法,維護(hù)者不覺(jué)得這是個(gè) bug,最后只能妥協(xié)使用 router.push
來(lái)解決,并將 vue-router
的依賴添加到 peerDependencies
中。在一些場(chǎng)景下,如果想封裝一個(gè)庫(kù)在各個(gè)框架中共同使用就不行了,在這里必須使用 router.push
才可以,我覺(jué)得還是不太好的。
以上就是vue3不能使用history.pushState修改url參數(shù)踩坑的詳細(xì)內(nèi)容,更多關(guān)于vue3修改url參數(shù)踩坑的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue3+elementplus基于el-table-v2封裝公用table組件詳細(xì)代碼
在日常開(kāi)發(fā)后端管理系統(tǒng)項(xiàng)目中,用于展示數(shù)據(jù)多會(huì)用表格進(jìn)行展示,下面這篇文章主要給大家介紹了關(guān)于vue3+elementplus基于el-table-v2封裝公用table組件的相關(guān)資料,需要的朋友可以參考下2023-12-12vue-cli3環(huán)境變量與分環(huán)境打包的方法示例
這篇文章主要介紹了vue-cli3環(huán)境變量與分環(huán)境打包的方法示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-02-02vue如何實(shí)現(xiàn)本項(xiàng)目頁(yè)面之間跳轉(zhuǎn)
這篇文章主要介紹了vue如何實(shí)現(xiàn)本項(xiàng)目頁(yè)面之間跳轉(zhuǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04vue.js框架實(shí)現(xiàn)表單排序和分頁(yè)效果
這篇文章主要為大家詳細(xì)介紹了vue.js框架實(shí)現(xiàn)表單排序和分頁(yè)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08vue項(xiàng)目中使用eslint+prettier規(guī)范與檢查代碼的方法
這篇文章主要介紹了vue項(xiàng)目中使用eslint+prettier規(guī)范與檢查代碼的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01關(guān)于移動(dòng)端與大屏幕自適應(yīng)適配方案
這篇文章主要介紹了關(guān)于移動(dòng)端與大屏幕自適應(yīng)適配方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10vue?electron實(shí)現(xiàn)無(wú)邊框窗口示例詳解
這篇文章主要為大家介紹了vue?electron實(shí)現(xiàn)無(wú)邊框窗口示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09