Vue.js?中?LocalStorage?與?SessionStorage操作示例最佳實(shí)踐
一、核心概念與特性對(duì)比
1.1 生命周期與作用域
| 特性 | LocalStorage | SessionStorage | 對(duì)比說(shuō)明 |
|---|---|---|---|
| ??生命周期?? | 永久存儲(chǔ)(瀏覽器關(guān)閉后仍存在) | 會(huì)話(huà)級(jí)存儲(chǔ)(標(biāo)簽頁(yè)關(guān)閉即清除) | LocalStorage 跨會(huì)話(huà)有效 |
| ??數(shù)據(jù)共享范圍?? | 同源所有窗口/標(biāo)簽頁(yè)共享 | 僅當(dāng)前標(biāo)簽頁(yè)有效 | 不同標(biāo)簽頁(yè)無(wú)法共享數(shù)據(jù) |
| ??典型存儲(chǔ)容量?? | 5-10MB(瀏覽器差異) | 5-10MB(與LocalStorage相同) | 均適合中小型數(shù)據(jù)存儲(chǔ) |
| ??數(shù)據(jù)可見(jiàn)性?? | 可通過(guò)瀏覽器開(kāi)發(fā)者工具查看 | 同左 | 敏感數(shù)據(jù)需加密處理 |
1.2 數(shù)據(jù)類(lèi)型限制
- ??存儲(chǔ)格式??:僅支持字符串類(lèi)型
- ??復(fù)雜數(shù)據(jù)處理??:需通過(guò)
JSON.stringify()/JSON.parse()轉(zhuǎn)換
// 存儲(chǔ)對(duì)象示例
localStorage.setItem('user', JSON.stringify({ name: '張三', age: 30 }));
const user = JSON.parse(localStorage.getItem('user'));二、基礎(chǔ)操作指南
2.1 核心 API 對(duì)比
| 方法 | LocalStorage | SessionStorage | 適用場(chǎng)景 |
|---|---|---|---|
setItem(key, value) | 永久存儲(chǔ)鍵值對(duì) | 當(dāng)前會(huì)話(huà)存儲(chǔ) | 需長(zhǎng)期保存的用戶(hù)偏好設(shè)置 |
getItem(key) | 讀取永久數(shù)據(jù) | 讀取會(huì)話(huà)數(shù)據(jù) | 獲取主題配置等持久化信息 |
removeItem(key) | 刪除永久數(shù)據(jù) | 刪除會(huì)話(huà)數(shù)據(jù) | 清除用戶(hù)登錄狀態(tài) |
clear() | 清空所有永久數(shù)據(jù) | 清空當(dāng)前會(huì)話(huà)數(shù)據(jù) | 重置應(yīng)用配置 |
2.2 完整操作示例
// 存儲(chǔ)數(shù)據(jù)(自動(dòng)序列化)
localStorage.setItem('theme', 'dark');
sessionStorage.setItem('cart', JSON.stringify([{id:1,name:'商品A'}]));
// 讀取數(shù)據(jù)(自動(dòng)反序列化)
const currentTheme = localStorage.getItem('theme') || 'light';
const cartItems = JSON.parse(sessionStorage.getItem('cart')) || [];
// 刪除數(shù)據(jù)
localStorage.removeItem('theme');
sessionStorage.removeItem('cart');
// 清空存儲(chǔ)
localStorage.clear();
sessionStorage.clear();三、進(jìn)階應(yīng)用場(chǎng)景
3.1 表單狀態(tài)保持(跨頁(yè)面)
// 在表單組件中
export default {
data() {
return {
formData: {
username: '',
password: ''
}
}
},
mounted() {
// 恢復(fù)上一次輸入
this.formData = JSON.parse(sessionStorage.getItem('formData')) || this.formData;
},
watch: {
formData: {
handler: 'saveDraft',
deep: true
}
},
methods: {
saveDraft() {
sessionStorage.setItem('formData', JSON.stringify(this.formData));
}
}
}3.2 用戶(hù)偏好設(shè)置管理
// 主題切換實(shí)現(xiàn)
const THEME_KEY = 'app_theme';
const DEFAULT_THEME = 'light';
// 獲取主題
const getCurrentTheme = () => {
return localStorage.getItem(THEME_KEY) || DEFAULT_THEME;
}
// 切換主題
const toggleTheme = () => {
const newTheme = getCurrentTheme() === 'light' ? 'dark' : 'light';
localStorage.setItem(THEME_KEY, newTheme);
document.body.className = newTheme;
}
// 初始化主題
document.addEventListener('DOMContentLoaded', () => {
const savedTheme = getCurrentTheme();
document.body.className = savedTheme;
});3.3 會(huì)話(huà)臨時(shí)數(shù)據(jù)存儲(chǔ)
// 購(gòu)物車(chē)臨時(shí)存儲(chǔ)(僅當(dāng)前標(biāo)簽頁(yè)有效)
const CART_KEY = 'shopping_cart';
// 添加商品
const addToCart = (product) => {
const cart = JSON.parse(sessionStorage.getItem(CART_KEY)) || [];
cart.push(product);
sessionStorage.setItem(CART_KEY, JSON.stringify(cart));
}
// 清空臨時(shí)數(shù)據(jù)(標(biāo)簽頁(yè)關(guān)閉自動(dòng)清除)
window.addEventListener('beforeunload', () => {
sessionStorage.removeItem(CART_KEY);
});四、最佳實(shí)踐與注意事項(xiàng)
4.1 數(shù)據(jù)安全策略
- ??敏感數(shù)據(jù)加密??:
import CryptoJS from 'crypto-js';
const SECRET_KEY = 'your-secret-key';
const encrypt = (data) => {
return CryptoJS.AES.encrypt(JSON.stringify(data), SECRET_KEY).toString();
}
const decrypt = (ciphertext) => {
const bytes = CryptoJS.AES.decrypt(ciphertext, SECRET_KEY);
return JSON.parse(bytes.toString(CryptoJS.enc.Utf8));
}
// 存儲(chǔ)加密數(shù)據(jù)
localStorage.setItem('token', encrypt('user_token_123'));- ??存儲(chǔ)容量監(jiān)控??:
const checkStorage = (storageType) => {
try {
const testData = 'x'.repeat(1024 * 1024); // 1MB測(cè)試數(shù)據(jù)
let count = 0;
while(true) {
storageType.setItem(`test_${count}`, testData);
count++;
}
} catch(e) {
const usedSpaceMB = (count * 1) / 1024; // 粗略估算已用空間
console.log(`已使用存儲(chǔ)空間:${usedSpaceMB.toFixed(2)}MB`);
return usedSpaceMB;
}
}
// 檢查L(zhǎng)ocalStorage剩余空間
checkStorage(localStorage);4.2 性能優(yōu)化方案
- ??批量操作優(yōu)化??:
// 批量寫(xiě)入優(yōu)化
const batchWrite = (storage, data) => {
const transaction = [];
Object.entries(data).forEach(([key, value]) => {
transaction.push({ type: 'set', key, value });
});
// 模擬批量操作(實(shí)際瀏覽器會(huì)自動(dòng)優(yōu)化)
transaction.forEach(({ key, value }) => {
storage.setItem(key, value);
});
}
// 使用示例
batchWrite(localStorage, {
theme: 'dark',
language: 'zh-CN',
version: '2.0.1'
});- ??內(nèi)存緩存策略??:
// 雙緩存機(jī)制(內(nèi)存+LocalStorage)
const createCache = (storageKey) => {
let memoryCache = JSON.parse(localStorage.getItem(storageKey)) || {};
return {
get: (key) => memoryCache[key],
set: (key, value) => {
memoryCache[key] = value;
localStorage.setItem(storageKey, JSON.stringify(memoryCache));
}
}
}
// 使用示例
const userCache = createCache('user_data');
userCache.set('profile', { name: '李四' });
const profile = userCache.get('profile');五、典型錯(cuò)誤與解決方案
5.1 跨域訪(fǎng)問(wèn)問(wèn)題
// 錯(cuò)誤示例:不同域名無(wú)法訪(fǎng)問(wèn)
// 在 https://a.com 無(wú)法訪(fǎng)問(wèn) https://b.com 的 localStorage
// 解決方案:使用 postMessage 進(jìn)行安全通信
window.addEventListener('message', (e) => {
if (e.origin === 'https://trusted-domain.com') {
localStorage.setItem('sharedData', e.data);
}
});5.2 存儲(chǔ)空間不足
// 錯(cuò)誤處理示例
try {
localStorage.setItem('largeData', new Array(10 * 1024 * 1024).fill('x').join(''));
} catch(e) {
if (e instanceof DOMException && e.code === 22) {
console.error('存儲(chǔ)空間不足,請(qǐng)清理緩存');
// 自動(dòng)清理過(guò)期數(shù)據(jù)
localStorage.removeItem('oldData');
}
}5.3 數(shù)據(jù)類(lèi)型錯(cuò)誤
// 類(lèi)型校驗(yàn)方案
const safeParse = (data) => {
try {
return JSON.parse(data);
} catch(e) {
console.error('數(shù)據(jù)解析失敗:', e);
return null;
}
}
const userInfo = safeParse(localStorage.getItem('user'));六、進(jìn)階應(yīng)用案例
6.1 離線(xiàn)應(yīng)用數(shù)據(jù)同步
// 離線(xiàn)數(shù)據(jù)緩存策略
const syncOfflineData = async () => {
if (!navigator.onLine) {
// 緩存待提交數(shù)據(jù)
const pendingData = getPendingData();
localStorage.setItem('offlineQueue', JSON.stringify(pendingData));
} else {
// 聯(lián)網(wǎng)時(shí)同步數(shù)據(jù)
const offlineData = JSON.parse(localStorage.getItem('offlineQueue') || '[]');
offlineData.forEach(async (item) => {
await fetch('/api/submit', { method: 'POST', body: JSON.stringify(item) });
});
localStorage.removeItem('offlineQueue');
}
}
// 監(jiān)聽(tīng)網(wǎng)絡(luò)狀態(tài)變化
window.addEventListener('online', syncOfflineData);6.2 多標(biāo)簽頁(yè)數(shù)據(jù)同步
// 使用 BroadcastChannel 實(shí)現(xiàn)跨標(biāo)簽頁(yè)通信
const channel = new BroadcastChannel('storage_sync');
// 監(jiān)聽(tīng)數(shù)據(jù)變化
channel.onmessage = (e) => {
if (e.data.type === 'storage-update') {
localStorage.setItem(e.data.key, e.data.value);
}
}
// 修改數(shù)據(jù)時(shí)廣播
const setItemWithBroadcast = (key, value) => {
localStorage.setItem(key, value);
channel.postMessage({ type: 'storage-update', key, value });
}通過(guò)合理運(yùn)用 LocalStorage 和 SessionStorage,開(kāi)發(fā)者可以顯著提升 Web 應(yīng)用的用戶(hù)體驗(yàn)和性能表現(xiàn)。建議根據(jù)數(shù)據(jù)特性選擇合適的存儲(chǔ)方案,并建立完善的存儲(chǔ)管理規(guī)范。
到此這篇關(guān)于Vue.js 中 LocalStorage 與 SessionStorage 深度實(shí)踐指南的文章就介紹到這了,更多相關(guān)vue.js localStorage 與 sessionStorage內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Vue瀏覽器緩存sessionStorage+localStorage+Cookie區(qū)別解析
- VUE使用localstorage和sessionstorage實(shí)現(xiàn)登錄示例詳解
- vue如何使用cookie、localStorage和sessionStorage進(jìn)行儲(chǔ)存數(shù)據(jù)
- vue中LocalStorage與SessionStorage的區(qū)別與用法
- vue項(xiàng)目如何監(jiān)聽(tīng)localStorage或sessionStorage的變化
- 詳解Vue中l(wèi)ocalstorage和sessionstorage的使用
相關(guān)文章
Vue?Router同名路由導(dǎo)致路由跳轉(zhuǎn)404的解決方法和避坑指南
在 Vue 項(xiàng)目開(kāi)發(fā)中,路由相關(guān)的問(wèn)題十分常見(jiàn),其中同名路由引發(fā)的404跳轉(zhuǎn)問(wèn)題極具迷惑性,很容易被誤判為權(quán)限問(wèn)題,本文將詳細(xì)記錄該問(wèn)題的排查過(guò)程、根源剖析,并結(jié)合 Vue Router 官方文檔給出解決方案和預(yù)防措施,幫助大家避坑2026-03-03
vue3.0 的 Composition API 的使用示例
這篇文章主要介紹了vue3.0 的 Composition API 的使用示例,幫助大家更好的理解和學(xué)習(xí)vue,感興趣的朋友可以了解下2020-10-10
Vue3?函數(shù)式彈窗的實(shí)例小結(jié)
這篇文章主要介紹了Vue3?函數(shù)式彈窗的實(shí)例小結(jié),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-11-11
vue項(xiàng)目中進(jìn)行svg組件封裝及配置方法步驟
本文主要介紹了vue項(xiàng)目中進(jìn)行svg組件封裝及配置方法步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
關(guān)于ELement?UI時(shí)間控件el-date-picker誤差8小時(shí)的問(wèn)題
本文探討了在使用Vue前端框架配合ElementUI開(kāi)發(fā)時(shí),遇到日期時(shí)間選擇器DateTimePicker的時(shí)間同步問(wèn)題,通過(guò)揭示中國(guó)東八區(qū)與格林威治時(shí)間的時(shí)差,作者提供了設(shè)置value-format屬性的解決方案,以確保后端接收到的正確時(shí)間格式2024-08-08
Vue之elementUI下拉菜單dropdown組件中command方法添加額外參數(shù)方式
這篇文章主要介紹了Vue之elementUI下拉菜單dropdown組件中command方法添加額外參數(shù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2025-06-06
Vue處理循環(huán)數(shù)據(jù)流程示例精講
這篇文章主要介紹了Vue處理循環(huán)數(shù)據(jù)流程,這個(gè)又是一個(gè)編程語(yǔ)言,?模版語(yǔ)法里面必不可少的一個(gè),?也是使用業(yè)務(wù)場(chǎng)景使用最多的一個(gè)環(huán)節(jié)。所以學(xué)會(huì)使用循環(huán)也是重中之重了2023-04-04
vue中使用sass及解決sass-loader版本過(guò)高導(dǎo)致的編譯錯(cuò)誤問(wèn)題
這篇文章主要介紹了vue中使用sass及解決sass-loader版本過(guò)高導(dǎo)致的編譯錯(cuò)誤問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-04-04

