如何利用Session Storage实现页面刷新后渲染购物车?
解决页面刷新后购物车丢失的问题
当前你的购物车数据仅存于浏览器内存,刷新页面就会重置。要利用SessionStorage实现购物车持久化,不能只单独存储商品ID的键,得把包含商品ID和对应数量的完整购物车对象存进去,这样刷新后才能恢复完整的购物车状态。
核心修改思路
- 页面初始化时,优先从SessionStorage读取之前保存的购物车数据,恢复到内存的
cart对象中 - 每次修改购物车(加/减商品)后,立即把最新的
cart对象转成JSON字符串,同步到SessionStorage - 封装统一的保存函数,避免重复编写存储逻辑
修改后的完整代码
JavaScript 部分
// 商品数据 let jsonFile = [ { "id": "001", "name": "Hoody Green", "desc": "Lorem ipsum dolor sit amet", "price": 65.00 }, { "id": "002", "name": "Cap Pink", "desc": "Lorem ipsum dolor sit amet", "price": 35.00 }, { "id": "003", "name": "Cap Black", "desc": "Lorem ipsum dolor sit amet", "price": 25.00 } ]; // 获取DOM元素 const productsContainer = document.getElementById('content'); const cartContainer = document.getElementById('cart'); // 把商品数据转成ID映射的对象 const products = jsonFile.reduce((accumulator, current) => { accumulator[current.id] = current; return accumulator; }, {}); // 从SessionStorage恢复购物车,无数据则初始化空对象 let cart = JSON.parse(sessionStorage.getItem('cart')) || {}; // 渲染商品项 const renderProductItem = data => { const { id, name, price, desc } = data; return ` <div class="item"> <p>ID - ${id}</p> <h2>${name}</h2> <p>${desc}</p> <b>${price}</b> <div class="goods__btn"> <button class="minus" onclick="minus('${id}')">−</button> <button class="plus" onclick="plus('${id}')">+</button> </div> </div> `; }; // 渲染购物车项 const renderCartItem = data => { const { id, name, price, quantity } = data; return ` <div class="cart-item"> ID ${id} (${name}): ${quantity} pcs. <button class="minus" onclick="minus('${id}')">−</button> <button class="plus" onclick="plus('${id}')">+</button> =$${price * quantity} </div> `; }; // 计算购物车总价 const getCartTotal = () => Object.entries(cart) .map(([id, quantity]) => products[id].price * quantity) .reduce((sum, current) => sum + current, 0); // 加初始值避免空数组报错 // 渲染购物车 const renderCart = () => { if (Object.keys(cart).length === 0) { cartContainer.innerHTML = 'Cart is empty'; return; } cartContainer.innerHTML = Object.entries(cart) .map(([id, quantity]) => renderCartItem({ ...products[id], quantity })) .join('') + `<div class="cart-total">Total: ${getCartTotal()}$</div>`; }; // 渲染商品列表 const showProducts = products => { productsContainer.innerHTML = Object.values(products) .map(renderProductItem) .join(''); }; // 保存购物车到SessionStorage const saveCartToSessionStorage = () => { sessionStorage.setItem('cart', JSON.stringify(cart)); }; // 页面加载时渲染商品和购物车 showProducts(products); renderCart(); // 增加商品 const plus = id => { cart[id] ??= 0; cart[id]++; saveCartToSessionStorage(); // 同步到SessionStorage renderCart(); }; // 减少商品 const minus = id => { if (cart[id]) { cart[id]--; if (cart[id] <= 0) { delete cart[id]; } saveCartToSessionStorage(); // 同步到SessionStorage renderCart(); } };
CSS 部分
h1, h2, h3, p, a, b, span { font-size: 1rem; margin: 0; padding: 0; } body { background: #eee; } .content { display: flex; justify-content: space-between; } .item { width: 30%; margin-right: 1rem; padding: 1rem; border: solid 1px #ccc; } .cart { margin-top: 1rem; background: #ddd; width: 100%; height: 100%; }
HTML 部分
<section class="goods"> <div class="container" id="content"> goods </div> </section> <section class="cart"> <div class="container" id="cart"> cart </div> </section>
关键修改点说明
- 购物车初始化:通过
JSON.parse(sessionStorage.getItem('cart')) || {}实现,优先读取SessionStorage中的数据,无数据则初始化空对象 - 购物车同步:封装
saveCartToSessionStorage函数,每次加减商品后调用,将内存中的购物车对象转成JSON字符串存入SessionStorage(SessionStorage仅支持字符串存储) - 总价计算优化:给
reduce方法添加初始值0,避免购物车为空时出现计算报错
内容的提问来源于stack exchange,提问作者Stan Law
相关产品推荐
相关产品推荐

