注销时在 Svelte-Routing 中隐藏路线

Hide Routes in Svelte-Routing when logged out

当我尝试在用户未登录时隐藏某些路由的页面时效果很好。但是一旦用户登录,当我使用 svelte-routingnavigate 方法导航到页面时,页面不再显示内容。但是一旦我点击路线,它们就会变得很好。难道我做错了什么?下面是基本设置。 You can also find it on github.

App.svelte

您可以在下面的示例中看到,我将 if-else 子句中的 Route 隐藏在 main HTML 标记下。当我在页面 /somewhere 上并且我也已经注销,然后单击登录,然后单击提交时,它应该将我带回 /somewhere 确实如此。但是在我单击 link Somewhere 之前,文本 Somewhere 不会像它应该的那样显示。预期的结果是它出现了。

<script>
import { Router, Link, Route, navigate } from "svelte-routing"
import Login from "./Login.svelte"
import Somewhere from "./Somewhere.svelte"
import Home from "./Home.svelte"

let user = null
var previousPath

$: user

function logout() {
    localStorage.clear()
    user = null
    navigate("/")
}

function loggedIn (event) {
    if (event) {
        user = { name: "George" }
        navigate(previousPath, { replace: true })
    }
}

function loggingIn() {
    previousPath = window.location.pathname
}

</script>

<Router>
    <h1>Test Login</h1>
    <nav>
        <Link to="/">Home</Link>
        {#if user === null}
        <Link to="/login" on:click={loggingIn}>Login</Link>
        {:else}
        <Link to="/somewhere">Somewhere</Link>
        <form on:submit={logout}>
            <input type="submit" value="Logout" />
        </form>
        {/if}
    </nav>
    <main>
        {#if user !== null}
        <Route path="/somewhere"><Somewhere /></Route>
        <Route path="/"><Home /></Route>
        {:else}
        <p>Please login</p>
        <Route path="/login"><Login on:loggedIn={loggedIn} /></Route>
        {/if}
    </main>
</Router>

这是其他页面:


Home.svelte

<p>Yellow!</p>

Login.svelte

<script>
import { createEventDispatcher } from "svelte";

const dispatch = createEventDispatcher()

function submit() {
    dispatch("loggedIn", true)
}
</script>

<form on:submit={submit}>
    <input type="submit" value="Submit" />
</form>

Somewhere.svelte

<p>Somewhere!</p>

经过一些调查,我发现您可以使用 tick 函数,如下所示:

import { tick } from "svelte"

...

async function loggedIn (event) {
    if (event) {
        user = { name: "George" }
        await tick()
        navigate(previousPath, { replace: true })
    }
}

它确实有效,但它看起来很丑。我不确定是否有更好更清洁的方法,所以你必须坚持下去。

tick 是一个函数,一旦应用了任何未决状态更改,它就会解析。在你的例子中,当 user 被修改时,它确保显示 {:else} 块的内容(虽然是空的),然后导航到以前的路径,这导致组件安装在 Route.