Appearance
本地存储(数据持久化)
18.1 localStorage 永久存储
localStorage 是浏览器提供的一种本地存储机制,用于在用户的浏览器中存储数据,数据会永久保存,即使关闭浏览器后再打开,数据仍然存在。
特点
- 存储容量较大,通常为 5MB
- 数据持久保存,不会自动过期
- 只能存储字符串类型的数据
- 同源策略限制,只能在同一域名下访问
基本操作
javascript
// 存储数据
localStorage.setItem("key", "value");
// 获取数据
const value = localStorage.getItem("key");
console.log(value); // 输出:value
// 删除数据
localStorage.removeItem("key");
// 清空所有数据
localStorage.clear();
// 获取存储的键名
const keys = Object.keys(localStorage);
console.log(keys);
// 获取存储的数量
const length = localStorage.length;
console.log(length);18.2 sessionStorage 临时存储
sessionStorage 与 localStorage 类似,但数据只在当前会话中有效,当关闭浏览器标签页或窗口时,数据会被清除。
特点
- 存储容量较大,通常为 5MB
- 数据只在当前会话中有效
- 只能存储字符串类型的数据
- 同源策略限制,只能在同一域名下访问
基本操作
javascript
// 存储数据
sessionStorage.setItem("key", "value");
// 获取数据
const value = sessionStorage.getItem("key");
console.log(value); // 输出:value
// 删除数据
sessionStorage.removeItem("key");
// 清空所有数据
sessionStorage.clear();
// 获取存储的键名
const keys = Object.keys(sessionStorage);
console.log(keys);
// 获取存储的数量
const length = sessionStorage.length;
console.log(length);18.3 存储 / 获取 / 删除数据
存储对象和数组
由于 localStorage 和 sessionStorage 只能存储字符串,我们需要使用 JSON.stringify() 将对象和数组转换为字符串,使用 JSON.parse() 将字符串转换回对象和数组。
javascript
// 存储对象
const user = {
name: "张三",
age: 25,
email: "zhangsan@example.com"
};
localStorage.setItem("user", JSON.stringify(user));
// 获取对象
const storedUser = JSON.parse(localStorage.getItem("user"));
console.log(storedUser.name); // 输出:张三
// 存储数组
const todos = ["学习 JavaScript", "练习编程", "完成项目"];
localStorage.setItem("todos", JSON.stringify(todos));
// 获取数组
const storedTodos = JSON.parse(localStorage.getItem("todos"));
console.log(storedTodos[0]); // 输出:学习 JavaScript存储和获取数字
javascript
// 存储数字
const score = 95;
localStorage.setItem("score", score.toString()); // 转换为字符串
// 获取数字
const storedScore = parseInt(localStorage.getItem("score"));
console.log(storedScore); // 输出:95
console.log(typeof storedScore); // 输出:number18.4 实战:记住用户名 / 购物车数据
实战 1:记住用户名
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>记住用户名</title>
<style>
.container {
max-width: 400px;
margin: 50px auto;
padding: 20px;
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
h2 {
text-align: center;
margin-bottom: 20px;
}
.form-group {
margin-bottom: 15px;
}
label {
display: block;
margin-bottom: 5px;
font-weight: bold;
}
input {
width: 100%;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
font-size: 16px;
}
.checkbox-group {
display: flex;
align-items: center;
}
.checkbox-group input {
width: auto;
margin-right: 10px;
}
button {
width: 100%;
padding: 10px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
margin-top: 20px;
}
button:hover {
background-color: #45a049;
}
.message {
margin-top: 20px;
padding: 10px;
background-color: #f0f0f0;
border-radius: 4px;
text-align: center;
}
</style>
</head>
<body>
<div class="container">
<h2>用户登录</h2>
<form id="loginForm">
<div class="form-group">
<label for="username">用户名</label>
<input type="text" id="username" name="username" placeholder="请输入用户名">
</div>
<div class="form-group">
<label for="password">密码</label>
<input type="password" id="password" name="password" placeholder="请输入密码">
</div>
<div class="form-group checkbox-group">
<input type="checkbox" id="remember" name="remember">
<label for="remember">记住用户名</label>
</div>
<button type="submit">登录</button>
</form>
<div class="message" id="message"></div>
</div>
<script>
const form = document.getElementById("loginForm");
const username = document.getElementById("username");
const password = document.getElementById("password");
const remember = document.getElementById("remember");
const message = document.getElementById("message");
// 页面加载时,从本地存储中获取用户名
window.onload = function() {
const storedUsername = localStorage.getItem("username");
if (storedUsername) {
username.value = storedUsername;
remember.checked = true;
}
};
// 表单提交事件
form.addEventListener("submit", function(event) {
event.preventDefault();
const usernameValue = username.value.trim();
const passwordValue = password.value;
if (usernameValue && passwordValue) {
// 模拟登录成功
message.textContent = `登录成功,欢迎 ${usernameValue}!`;
message.style.backgroundColor = "#d4edda";
message.style.color = "#155724";
// 如果勾选了记住用户名,存储到本地存储
if (remember.checked) {
localStorage.setItem("username", usernameValue);
} else {
localStorage.removeItem("username");
}
// 清空密码
password.value = "";
} else {
message.textContent = "请输入用户名和密码";
message.style.backgroundColor = "#f8d7da";
message.style.color = "#721c24";
}
});
</script>
</body>
</html>实战 2:购物车数据
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>购物车示例</title>
<style>
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: Arial, sans-serif;
padding: 20px;
}
.container {
max-width: 800px;
margin: 0 auto;
}
h1 {
text-align: center;
margin-bottom: 30px;
}
.products {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.product {
border: 1px solid #ddd;
border-radius: 8px;
padding: 15px;
text-align: center;
}
.product h3 {
margin-bottom: 10px;
}
.product .price {
font-size: 18px;
font-weight: bold;
color: #f44336;
margin-bottom: 15px;
}
.product button {
padding: 8px 16px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.product button:hover {
background-color: #45a049;
}
.cart {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
}
.cart h2 {
margin-bottom: 20px;
}
.cart-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #eee;
}
.cart-item:last-child {
border-bottom: none;
}
.cart-item .name {
flex: 1;
}
.cart-item .price {
margin: 0 20px;
}
.cart-item .quantity {
margin: 0 20px;
}
.cart-item button {
padding: 5px 10px;
background-color: #f44336;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.cart-item button:hover {
background-color: #d32f2f;
}
.cart-total {
margin-top: 20px;
text-align: right;
font-size: 18px;
font-weight: bold;
}
.cart-empty {
text-align: center;
padding: 20px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>购物车示例</h1>
<div class="products">
<div class="product">
<h3>商品 1</h3>
<div class="price">¥100</div>
<button onclick="addToCart('商品 1', 100)">加入购物车</button>
</div>
<div class="product">
<h3>商品 2</h3>
<div class="price">¥200</div>
<button onclick="addToCart('商品 2', 200)">加入购物车</button>
</div>
<div class="product">
<h3>商品 3</h3>
<div class="price">¥150</div>
<button onclick="addToCart('商品 3', 150)">加入购物车</button>
</div>
<div class="product">
<h3>商品 4</h3>
<div class="price">¥300</div>
<button onclick="addToCart('商品 4', 300)">加入购物车</button>
</div>
</div>
<div class="cart">
<h2>购物车</h2>
<div id="cartItems"></div>
<div class="cart-total" id="cartTotal">总计:¥0</div>
</div>
</div>
<script>
// 从本地存储中获取购物车数据
function getCart() {
const cart = localStorage.getItem("cart");
return cart ? JSON.parse(cart) : [];
}
// 保存购物车数据到本地存储
function saveCart(cart) {
localStorage.setItem("cart", JSON.stringify(cart));
}
// 添加商品到购物车
function addToCart(name, price) {
const cart = getCart();
// 检查商品是否已在购物车中
const existingItem = cart.find(item => item.name === name);
if (existingItem) {
// 如果商品已存在,增加数量
existingItem.quantity++;
} else {
// 如果商品不存在,添加新商品
cart.push({ name, price, quantity: 1 });
}
saveCart(cart);
updateCartUI();
}
// 从购物车中删除商品
function removeFromCart(name) {
const cart = getCart();
const updatedCart = cart.filter(item => item.name !== name);
saveCart(updatedCart);
updateCartUI();
}
// 更新购物车 UI
function updateCartUI() {
const cart = getCart();
const cartItems = document.getElementById("cartItems");
const cartTotal = document.getElementById("cartTotal");
if (cart.length === 0) {
cartItems.innerHTML = '<div class="cart-empty">购物车为空</div>';
cartTotal.textContent = "总计:¥0";
return;
}
let html = '';
let total = 0;
cart.forEach(item => {
const itemTotal = item.price * item.quantity;
total += itemTotal;
html += `
<div class="cart-item">
<div class="name">${item.name}</div>
<div class="price">¥${item.price}</div>
<div class="quantity">×${item.quantity}</div>
<div class="item-total">¥${itemTotal}</div>
<button onclick="removeFromCart('${item.name}')">删除</button>
</div>
`;
});
cartItems.innerHTML = html;
cartTotal.textContent = `总计:¥${total}`;
}
// 页面加载时更新购物车 UI
window.onload = function() {
updateCartUI();
};
</script>
</body>
</html>小结
localStorage:永久存储,数据不会自动过期sessionStorage:临时存储,数据在会话结束后清除- 两者都只能存储字符串类型的数据,需要使用
JSON.stringify()和JSON.parse()处理对象和数组 - 存储容量通常为 5MB
- 遵循同源策略,只能在同一域名下访问
- 本地存储在网页开发中常用于:
- 记住用户偏好设置
- 存储购物车数据
- 缓存用户数据
- 实现离线应用
- 注意不要存储敏感信息,因为本地存储是明文存储的
