在很多公司中,內部都會封裝一些適用于公司內部業務的方法庫來提高整個團隊的開發效率,比如:
而在 Vue3 項目中,這種方法庫表現為:hooks庫,市面上有很多優秀的庫,比如:vueuse。
最近我在面試中,喜歡問一道有關于 hooks 的開放問題:二次封裝一個 loaclStorage 的 hooks 時,需要考慮哪些問題呢?
其實這是一道很簡單的題,只不過想考考面試者在做業務的時候,會不會考慮更多的邊界情況~接下來說說我對這個問題的小小的理解(可能也不是很全面)。
比如我現在一個域名下有兩個子項目:
且這兩個項目都需要存儲 userInfo,那要怎么防止這兩組數據互相污染呢?所以需要注意命名,在存儲的時候加上對應的項目名前綴,或者其他標識符,保證這組數據是唯一的
const PROJECT_NAME = 'test-project'localStorage.setItem( `${PROJECT_NAME}_userInfo`, JSON.stringify({ name: 'lsx' }))
請看一個例子,假如我們存儲一段信息,類型是 string
// 存數據const set = () => { const info = get() if (!info) { localStorage.setItem( `${PROJECT_NAME}_info`, 'info_string' ) }}// 取數據const get = () => { const info = localStorage.getItem( `${PROJECT_NAME}_info` ) return info}
然后項目上線了一段時間,但是這個時候,突然決定要換成 object 類型了,這時候對應的存取方法也變了
// 存數據const set = () => { const info = get() if (!info) { localStorage.setItem( `${PROJECT_NAME}_info`, JSON.stringify({ name: 'lsx' }) ) }}// 取數據const get = () => { const info = localStorage.getItem( `${PROJECT_NAME}_info` ) return JSON.parse(info)}
但是這樣其實是有隱患的,因為項目已經上線了一段時間,有些用戶已經存過這個數據了,且存的是 string 類型,但是新版本上線之后,取數據卻用了 object 的方式去取數據,這就導致了JSON.parse(字符串)會報錯,影響正常的業務邏輯~
所以最好是加一個版本號,或者做一下錯誤兼容,這樣就能避免了~
const PROJECT_NAME = 'test-project'// 每次升級時改變版本號,規則自己定const VERSION = 1// 存數據localStorage.setItem( `${PROJECT_NAME}_userInfo_${VERSION}`, JSON.stringify({ name: 'lsx' }))// 取數據localStorage.getItem( `${PROJECT_NAME}_userInfo_${VERSION}`)
時效性,那就是給存進去的數據加一個時效,過了某個時間,這個數據就時效了,方法就是每次存數據進去的時候,加一個時間戳:
// 原來localStorage.setItem( `${PROJECT_NAME}_userInfo`, JSON.stringify({ name: 'lsx' }))const TIME_OUT = 3 * 60 * 60 * 1000// 加時間戳localStorage.setItem( `${PROJECT_NAME}_userInfo`, JSON.stringify({ data: { name: 'lsx' }, // 記錄當前時間 time: new Date().getTime() }))// 取數據時判斷時間戳const get = () => { let info = localStorage.getItem( `${PROJECT_NAME}_userInfo_${VERSION}` ) info = JSON.parse(info) const now = new Date().getTime() if (now - info.time >= TIME_OUT) { localStorage.removeItem( `${PROJECT_NAME}_userInfo_${VERSION}` ) return null } return info}
有一些數據我們不得不存在 localStorage 中,但是又不想被用戶看到,這時候就需要進行加密了(加密規則自己定):
// 加密函數const encrypt = (v) => {}// 解密函數const decrypt = (v) => {}// 存數據localStorage.setItem( `${PROJECT_NAME}_userInfo_${VERSION}`, // 加密 encrypt(JSON.stringify({ name: 'lsx' })))// 取數據 解密decrypt(localStorage.getItem( `${PROJECT_NAME}_userInfo_${VERSION}`))
SSR 就是服務端渲染,是在服務端運行代碼,拼接成一個頁面,發送到瀏覽器去展示出來,所以在服務端是使用不了 localStorage 的,因為不是瀏覽器環境,所以你像封裝一個比較通用的 localStorage,得兼顧 SSR 的情況:
// 在 SSR 中使用對象替代 localStorageconst SSRStorage = { map: {}, setItem(v) { this.map[key] = v }, getItem(key) { return this.map[key] }}let storage = null// 判斷環境if (!window) { storage = SSRStorage} else { storage = window.localStorage}
本文鏈接:http://www.www897cc.com/showinfo-26-76567-0.html我面試最喜歡問的開放題:如何嚴謹二次封裝 localStorage?
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: 面試官:工作中處理過什么復雜的前端需求,如何解決的?
下一篇: Redis鎖被別人釋放怎么辦