如何将Svelte Store数据存入LocalStorage避免页面刷新丢失?
解决Svelte Store数据刷新丢失的LocalStorage持久化方案
核心思路
给Svelte Store添加LocalStorage同步逻辑:
- 初始化Store时优先从LocalStorage读取数据
- 监听Store变化,每次更新自动将数据存入LocalStorage
- 仅当LocalStorage无数据时发起API请求,避免重复请求
修改后的Store代码
import { writable } from "svelte/store"; // 自定义持久化writable函数,可复用 function persistedWritable(key, initialValue) { // 从LocalStorage读取并解析数据 const stored = localStorage.getItem(key); const initial = stored ? JSON.parse(stored) : initialValue; const { subscribe, set, update } = writable(initial); return { subscribe, set: (value) => { // 更新时同步存入LocalStorage localStorage.setItem(key, JSON.stringify(value)); set(value); }, update: (callback) => { update((current) => { const newValue = callback(current); localStorage.setItem(key, JSON.stringify(newValue)); return newValue; }); } }; } // 用自定义持久化store替代原生writable export const leagueTable = persistedWritable('leagueTable', []); const fetchTable = async () => { // 仅当LocalStorage无数据时才请求API if (!localStorage.getItem('leagueTable')) { const url = `https://soccer.sportmonks.com/api/v2.0/standings/season/19734?api_token=API_KEY`; const res = await fetch(url); const data = await res.json(); leagueTable.set(data.data); } }; fetchTable();
组件代码修正
原组件中tableMaps为普通常量,无法响应Store数据变化,需改为响应式声明;同时修正循环变量名匹配问题:
<script> import { leagueTable } from "../stores/league-standings-stores" // 响应式声明,随$leagueTable变化自动更新 $: tableMaps = $leagueTable.map(item => item.standings.data).flat(); $: tablePositions = tableMaps; </script> {#each tablePositions as tablePosition} <div class="standings-table flex gap-9 mb-2 pb-4 pt-3 border-b border-[#303041]"> <div class="team-details flex gap-4 w-full" id="td"> <p class="w-[18px]">{tablePosition.position}</p> <img src="{tablePosition.team.data.logo_path}" alt="{tablePosition.team_name} logo" class="w-[1.5em] object-scale-down"> <p>{tablePosition.team_name}</p> </div> <div class="team-stats flex gap-5 text-left child:w-5 child:text-center w-full"> <p>{tablePosition.overall.games_played}</p> <p>{tablePosition.overall.won}</p> <p>{tablePosition.overall.draw}</p> <p>{tablePosition.overall.lost}</p> <p>{tablePosition.overall.goals_scored}</p> <p>{tablePosition.overall.goals_against}</p> <p>{tablePosition.total.goal_difference}</p> <p>{tablePosition.overall.points}</p> <p class="!w-[78px] !text-left">{tablePosition.recent_form}</p> </div> </div> {/each}
关键说明
persistedWritable封装了LocalStorage读写逻辑,可直接复用在其他需要持久化的Store上- 初始化优先读取LocalStorage,避免每次刷新重复请求API
- 响应式声明
$:确保数据变化时自动更新视图,解决原组件可能出现的无数据渲染问题
内容的提问来源于stack exchange,提问作者joshisitalian
相关产品推荐
相关产品推荐

