如何在 Svelte 中创建可在所有页面中使用的上下文?

Chu*_*Kul 2 svelte sveltekit

我目前正在学习 Svelte,我想为这个副项目创建一个身份验证流程。通常,在 React 中,我习惯使用上下文保存身份验证信息。

<AuthContext>
   <App />
<AuthContext>
Run Code Online (Sandbox Code Playgroud)

我想知道 Svelte 是否也可以执行类似的方法?所有教程都是基于组件的上下文。我想在我的应用程序中调用 getContext('authContext') 。

AuthContext.svelte

<script lang='ts'>
      import { writable } from 'svelte/store'
      import { onDestroy, setContext } from 'svelte'
      import {getAuth, type User, onAuthStateChanged} from 'firebase/auth'
    
      const auth = getAuth()
      const userStore = writable<User | null>(null)
      const isLoggedIn = writable<boolean>(false)
      
      const contexts = {
        isLoggedIn,
        userStore,
        logOut,
      }
      
      const unsubscribe =  onAuthStateChanged(auth, (user) => {
        if(user) {
          userStore.set(user)
          isLoggedIn.set(true)
        }
      })

      setContext('authContext', contexts)
 
    function logOut() {
      auth.signOut()
      isLoggedIn.set(false)
    }
    
    
      onDestroy(() => unsubscribe())
    
</script>
    
Run Code Online (Sandbox Code Playgroud)

我在 __layout.svelte 中调用了 getContext:

<script lang='ts'>
      import {getContext} from 'svelte'

      const {isLoggedIn} = getContext('authContext')
      
</script>
Run Code Online (Sandbox Code Playgroud)

它会产生以下错误:

无法解构 的属性'isLoggedIn''__vite_ssr_import_1__.getContext(...)'因为它未定义。

Ste*_*aes 6

对于要在所有页面中使用的“上下文”,您可能应该只使用常规商店。

在外部 javascript 文件中定义存储:

// ./stores.js
import { writable } from 'svelte/store';

export const loggedIn = writable(false);
export const user = writable(null);
Run Code Online (Sandbox Code Playgroud)

并在必要时简单地导入它:

<!-- Component.svelte -->
<script>
  import { loggedIn } from './stores.js';
</script>
Run Code Online (Sandbox Code Playgroud)