How to strictly encapsulate localStorage twice?

In many companies, some method libraries suitable for the company's internal business are encapsulated internally to improve the development efficiency of the entire team, such as:
1. Anti-shake throttling
2. Lazy loading, virtual scrolling
3. DOM addition, deletion, modification, search, move, and drag 4.Manage
status

In the Vue3 project, this method library is represented by: hooks library. There are many excellent libraries on the market, such as: vueuse.
Recently, during an interview, I like to ask an open question about hooks: secondary encapsulation of a loaclStorage hook. What issues need to be considered?
In fact, this is a very simple question. I just want to test whether the interviewer will consider more boundary situations when doing business. Next, let me talk about my little understanding of this question (it may not be very comprehensive)

Pay attention to naming to prevent contamination.
For example, I currently have two sub-projects under one domain name:

Project A and Project
B
both need to store userInfo, so how to prevent these two sets of data from contaminating each other? Therefore, you need to pay attention to naming and add the corresponding project name prefix or other identifier when storing to ensure that this set of data is unique.

const PROJECT_NAME = ‘test-project’
localStorage.setItem(
${PROJECT_NAME}_userInfo,
JSON.stringify({ name: ‘lsx’ })
)

Pay attention to the version and prevent iteration
. Please look at an example. If we store a piece of information, the type is string
// Store data
const set = () => { const info = get()if (!info) { localStorage.setItem(,'info_string ')}}// Get dataconst get = () => { const info = localStorage.getItem()return info}Then the project has been online for a while, but at this time, it was suddenly decided to change to the object type. At this time, the corresponding The access method has also changed// Storing dataconst set = () => { const info = get()if (!info) { localStorage.setItem(,JSON.stringify({ name: 'lsx' }))}}// Get dataconst get = () => {



${PROJECT_NAME}_info







${PROJECT_NAME}_info









${PROJECT_NAME}_info






const info = localStorage.getItem(
${PROJECT_NAME}_info
)
return JSON.parse(info)
}
But this actually has hidden dangers, because the project has been online for a while, and some users have already saved this data, and the saved data is of string type, but the new After the version is online, the object method is used to retrieve the data, which causes JSON.parse (string) to report an error and affects the normal business logic~ So it is best to
add a version number or make error compatibility , this can be avoided ~

const PROJECT_NAME = 'test-project'
// Change the version number every time you upgrade, the rules set
const VERSION = 1

// Store data
localStorage.setItem(
${PROJECT_NAME}_userInfo_${VERSION},
JSON.stringify({ name: 'lsx' })
)

// Get data
localStorage.getItem(
${PROJECT_NAME}_userInfo_${VERSION}
)
timeliness, privacy
timeliness, that is, add a timeliness to the stored data. After a certain time, the data will be timely. The method is that every time you save data, Add a timestamp
// original
localStorage.setItem(
${PROJECT_NAME}_userInfo,
JSON.stringify({ name: 'lsx' })
)

const TIME_OUT = 3 * 60 * 60 * 1000
// Add timestamp
localStorage.setItem(
${PROJECT_NAME}_userInfo,
JSON.stringify({ data: { name: 'lsx' }, // Record current time time: new Date().getTime() }) )




//Judge the timestamp when fetching data
const get = () => { let info = localStorage.getItem( ) info = JSON.parse(info) const now = new Date().getTime() if (now - info.time >= TIME_OUT) { localStorage.removeItem( ) return null } return info } There is some data that we have to store in localStorage, but we don’t want it to be seen by users. At this time, we need to encrypt it (the encryption rules are determined by ourselves)

${PROJECT_NAME}_userInfo_${VERSION}





${PROJECT_NAME}_userInfo_${VERSION}





// encryption function
const encrypt = (v) => {}
// decryption function
const decrypt = (v) => {}

// store data
localStorage.setItem(
${PROJECT_NAME}_userInfo_${VERSION},
// encrypt
encrypt(JSON.stringify({ name: 'lsx' }))
)

// Get data decryption
decrypt(localStorage.getItem(
${PROJECT_NAME}_userInfo_${VERSION}
))

Compatible with SSR
SSR is server-side rendering. It runs code on the server, splices it into a page, and sends it to the browser for display. Therefore, localStorage cannot be used on the server because it is not a browser environment, so you encapsulate a comparison Universal localStorage must take SSR into consideration

// Use objects in SSR instead of localStorage
const SSRStorage = { map: {}, setItem(v) { this.map[key] = v }, getItem(key) { return this.map[key] } } let storage = null // Judgment environment if (!window) { storage = SSRStorage } else { storage = window.localStorage }














Guess you like

Origin blog.csdn.net/longxiaobao123/article/details/132777914