You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用$语法访问嵌套或命名空间下的Svelte store

核心原因

Svelte的$语法属于编译时预处理的语法糖,编译器仅会识别组件script块顶层作用域内声明的store变量,不会递归解析对象属性中嵌套的store,因此直接访问命名空间对象下的store属性无法触发$语法的自动订阅逻辑。

解决方案:将命名空间对象本身改造为符合契约的store

通过Svelte内置的derived方法聚合所有子store的状态,让默认导出的命名空间对象本身满足store契约(即存在subscribe方法),即可直接用$语法访问聚合后的所有子状态,同时保留原有的方法调用能力。

修改后的User.store.js代码

import { readable, writable, derived } from 'svelte/store';

const store = writable({
    token: null,
});

const loggedIn = readable(false, (set) => store.subscribe(s => set(!!s.token)));

const login = async (token) => store.set({token});
// 修复原代码语法错误:缺失右括号
const logout = async () => store.set({token: null});

const state = {subscribe: store.subscribe}

// 聚合所有子store的状态
const rootStore = derived(
  [state, loggedIn],
  ([_state, _loggedIn]) => ({
    state: _state,
    loggedIn: _loggedIn
  })
)

// 合并subscribe、子store、操作方法到默认导出对象
const nameSpacedStore = {
  // 实现store契约,支持$语法直接作用于该对象
  subscribe: rootStore.subscribe,
  // 暴露原始子store和方法,兼容原有解构导入的用法
  state,
  loggedIn,
  login,
  logout
}

export { state, loggedIn, login, logout }
export default nameSpacedStore

组件内使用方式

<script>
import NameSpaced from './User.store.js'
</script>

<!-- 直接生效,返回loggedIn的实时状态 -->
LoggedIn: {$NameSpaced.loggedIn}
<!-- 也可直接访问基础状态 -->
User Token: {$NameSpaced.state.token}
<!-- 调用方法逻辑不变 -->
<button on:click={() => NameSpaced.login('test_token')}>登录</button>
备选轻量化方案

如果不想改造store导出逻辑,也可以在组件内一次性完成别名解构,避免重复声明:

<script>
import NameSpaced from './User.store.js'
const { loggedIn: userLoggedIn, state: userState } = NameSpaced
</script>

LoggedIn: {$userLoggedIn}
Token: {$userState.token}

内容的提问来源于stack exchange,提问作者Seltsam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 20:21:02