如何在SvelteKit中创建全局变量存储用户状态与Token?
在最新版SvelteKit中实现全局用户状态与Token存储
以下是几种靠谱的实现方式,可根据你的场景选择:
方法1:使用Svelte Stores(客户端全局状态管理)
这是最常用的客户端状态共享方案,适合纯前端场景,步骤如下:
- 在
src/lib目录下创建stores.ts文件,定义可写存储:
import { writable } from 'svelte/store'; // 从localStorage读取初始值,实现刷新页面不丢失 const initialUser = JSON.parse(localStorage.getItem('userState') || 'null'); export const userState = writable(initialUser); const initialToken = localStorage.getItem('authToken') || ''; export const authToken = writable(initialToken); // 封装登录/退出方法,统一处理状态更新与持久化 export function login(userData: any, token: string) { userState.set(userData); authToken.set(token); localStorage.setItem('userState', JSON.stringify(userData)); localStorage.setItem('authToken', token); } export function logout() { userState.set(null); authToken.set(''); localStorage.removeItem('userState'); localStorage.removeItem('authToken'); }
- 在任意组件中直接导入使用:
<script> import { userState, authToken, logout } from '$lib/stores'; </script> {#if $userState} <p>当前用户:{$userState.name}</p> <button on:click={logout}>退出登录</button> {:else} <p>请登录</p> {/if}
注意:通过$前缀可以自动订阅store的更新,组件会实时响应状态变化。
方法2:结合Hooks + Stores(服务端+客户端共享)
如果需要服务端渲染时也能获取用户状态(比如从Cookie或数据库读取),可以用这种方案:
- 在
src/hooks.server.ts中,从请求中提取Token并验证用户信息,存入locals:
import type { Handle } from '@sveltejs/kit'; export const handle: Handle = async ({ event, resolve }) => { const token = event.cookies.get('authToken'); if (token) { // 调用接口验证Token,获取用户信息 const userData = await fetchUserInfo(token); event.locals.user = userData; event.locals.token = token; } return resolve(event); };
- 在
src/routes/+layout.server.ts中,将服务端locals的数据传递到客户端:
import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = async ({ locals }) => { return { user: locals.user, token: locals.token }; };
- 在根布局
src/routes/+layout.svelte中,将页面数据同步到store:
<script> import { userState, authToken } from '$lib/stores'; export let data; // 同步服务端传递的状态到全局store $userState = data.user; $authToken = data.token; </script> <slot />
这样无论服务端渲染还是客户端路由跳转,全局状态都能保持一致。
补充:类型安全配置
为了获得更好的类型提示,修改src/app.d.ts:
declare global { namespace App { interface Locals { user: User | null; token: string | null; } interface PageData { user: User | null; token: string | null; } type User = { id: string; name: string; // 按需添加其他用户字段 }; } } export {};
内容的提问来源于stack exchange,提问作者DavidF
相关产品推荐
相关产品推荐

