在Vue項(xiàng)目中使用URL Query保存和恢復(fù)搜索條件的操作指南
引言
在實(shí)際的前端開發(fā)中,我們經(jīng)常會(huì)遇到這樣的需求:
用戶在列表頁(yè)輸入了一些搜索條件,點(diǎn)擊某一條數(shù)據(jù)進(jìn)入詳情頁(yè);當(dāng)他返回列表頁(yè)時(shí),希望搜索條件能被 記住,而不是重新初始化。
常見的解決方案有三種:
- 使用 全局狀態(tài)管理(Vuex/Pinia) 保存搜索條件。
- 使用
keep-alive緩存頁(yè)面組件。 - 使用 URL Query 參數(shù) 把搜索條件保存在地址欄中。
本文介紹的是第三種方式,通過封裝一個(gè) useQueryStorage Hook,把對(duì)象序列化到 URL 的 querystring 中,從而實(shí)現(xiàn)搜索條件的記憶。
核心代碼
import { isEqual } from "lodash-es";
import { useRouter, useRoute } from "vue-router";
export const useQueryStorage = <T>(key: string = "savedQuery") => {
const router = useRouter();
const route = useRoute();
// 把對(duì)象以 JSON 的格式存入到 URL 的 querystring 中
const saveObjectToQueryString = (obj: T) => {
const query = parseSavedObjectFromQueryString();
if (!isEqual(query, obj)) {
router.replace({
query: {
...route.query,
[key]: encodeURIComponent(JSON.stringify(obj)),
},
});
}
};
// 從 URL 的 querystring 中解析出對(duì)象
const parseSavedObjectFromQueryString: () => T | null = () => {
let query = route.query[key];
if (query && typeof query === "string") {
query = JSON.parse(decodeURIComponent(query));
return query as T;
}
return null;
};
return {
getQ: parseSavedObjectFromQueryString,
setQ: saveObjectToQueryString,
};
};
代碼解析
1. 存儲(chǔ)對(duì)象到 URL
const saveObjectToQueryString = (obj: T) => {
const query = parseSavedObjectFromQueryString();
if (!isEqual(query, obj)) {
router.replace({
query: {
...route.query,
[key]: encodeURIComponent(JSON.stringify(obj)),
},
});
}
};
這里使用了 JSON.stringify 把對(duì)象轉(zhuǎn)成字符串,再用 encodeURIComponent 確保字符串在 URL 中不會(huì)出錯(cuò)。
為什么要用 lodash.isEqual?
因?yàn)?Vue Router 的 replace 會(huì)更新 URL,如果我們每次都寫入同樣的對(duì)象,就會(huì)產(chǎn)生冗余的路由更新。用 isEqual 做深度比較,可以避免不必要的刷新。
2. 從 URL 解析對(duì)象
const parseSavedObjectFromQueryString: () => T | null = () => {
let query = route.query[key];
if (query && typeof query === "string") {
query = JSON.parse(decodeURIComponent(query));
return query as T;
}
return null;
};
這一段邏輯就是把 querystring 里的值取出來,做 解碼 + JSON 反序列化,還原成原來的對(duì)象。
3. Hook 的返回值
return {
getQ: parseSavedObjectFromQueryString,
setQ: saveObjectToQueryString,
};
對(duì)外提供兩個(gè)方法:
getQ():獲取保存的搜索條件。setQ(obj):設(shè)置搜索條件并保存到 URL。
這樣調(diào)用方的代碼就會(huì)非常簡(jiǎn)潔。
使用示例
在列表頁(yè)中:
const { getQ, setQ } = useQueryStorage<{ keyword: string; page: number }>();
// 初始化時(shí)恢復(fù)
const saved = getQ();
if (saved) {
searchForm.keyword = saved.keyword;
searchForm.page = saved.page;
}
// 用戶點(diǎn)擊搜索時(shí)保存
function handleSearch() {
setQ({ keyword: searchForm.keyword, page: searchForm.page });
}
當(dāng)用戶進(jìn)入詳情頁(yè)再返回時(shí),URL 中依然保存了搜索條件,頁(yè)面加載時(shí)會(huì)自動(dòng)恢復(fù)。
優(yōu)點(diǎn)總結(jié)
- 刷新不丟失
因?yàn)闋顟B(tài)存放在 URL 里,刷新后依然可以恢復(fù)。 - 可分享鏈接
用戶可以直接復(fù)制 URL,別人打開時(shí)能看到相同的搜索條件。 - 解耦全局狀態(tài)
不依賴 Vuex/Pinia,邏輯簡(jiǎn)單清晰。
缺點(diǎn)是:如果搜索條件非常復(fù)雜,URL 會(huì)變長(zhǎng),可能不太美觀。
總結(jié)
useQueryStorage 是一個(gè)非常實(shí)用的小 Hook,通過 encodeURIComponent 和 JSON.stringify 將對(duì)象持久化到 URL 的 query 參數(shù)中,結(jié)合 lodash.isEqual 避免重復(fù)寫入,能很好地解決 列表頁(yè)返回時(shí)記住搜索條件 的問題。
以上就是在Vue項(xiàng)目中使用URL Query保存和恢復(fù)搜索條件的操作指南的詳細(xì)內(nèi)容,更多關(guān)于Vue URL Query保存和恢復(fù)搜索條件的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue第三方庫(kù)中存在擴(kuò)展運(yùn)算符報(bào)錯(cuò)問題的解決方案
這篇文章主要介紹了vue第三方庫(kù)中存在擴(kuò)展運(yùn)算符報(bào)錯(cuò)問題,本文給大家分享解決方案,通過結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07
Vue build過程取消console debugger控制臺(tái)信息輸出方法詳解
這篇文章主要為大家介紹了Vue build過程取消console debugger控制臺(tái)信息輸出方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
對(duì) Vue-Router 進(jìn)行單元測(cè)試的方法
這篇文章主要介紹了對(duì) Vue-Router 進(jìn)行單元測(cè)試的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11
el-form組件清除校驗(yàn)提示正確方法(前端技能提升)
el-form組件提供了表單驗(yàn)證的功能,可以通過在el-form上綁定rules屬性,并在el-form-item上設(shè)置prop屬性來進(jìn)行校驗(yàn),這篇文章主要給大家介紹了關(guān)于el-form組件清除校驗(yàn)提示正確方法(前端技能提升)的相關(guān)資料,需要的朋友可以參考下2023-12-12
vant-list上拉加載onload事件觸發(fā)多次問題及解決
這篇文章主要介紹了vant-list上拉加載onload事件觸發(fā)多次問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
Vue簡(jiǎn)易注冊(cè)頁(yè)面+發(fā)送驗(yàn)證碼功能的實(shí)現(xiàn)示例
本文主要介紹了Vue簡(jiǎn)易注冊(cè)頁(yè)面+發(fā)送驗(yàn)證碼功能的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11

