边栏配置文件 link 需要在 sapper/svelte 中登录后重新加载

Sidebar profile link requires reload after login in sapper/svelte

我有以下工兵布局。

<script>
    import { onMount } from "svelte";
    import { goto, stores } from "@sapper/app";
    import { mdiLogin, mdiLogout, mdiGithub } from "@mdi/js";

    import "./_app.scss";
    import "./_elevated.scss";

    import TopAppBar, { Row, Section, Title } from "@smui/top-app-bar";
    import { Scrim, AppContent } from "@smui/drawer";
    import IconButton from "@smui/icon-button";
    // import List, { Item, Text } from "@smui/list";
    import { Icon } from "@smui/common";
    import A from "@smui/common/A.svelte";
    import Drawer from "../components/_Drawer.svelte";

    import { post } from "utils.js";

    const { page, session } = stores();

    async function logout() {
        await post(`auth/logout`);
        $session.user = null;
        localStorage.removeItem("jwt");
        goto("/");
    }

    // const iframe = $page.path.startsWith("/demo/top-app-bar-iframe");

    let mainContent;
    let drawerOpen = false;
    let miniWindow = false;
    // let user = undefined;

    onMount(async () => {
        setMiniWindow;
        // const unsubscribe = session.subscribe(async ($session) => {
        //  if($session.user){
        //      user = $session.user;
        //      console.log(user);
        //  }
        // });
        // return unsubscribe;
    });

    function setMiniWindow() {
        miniWindow = window.innerWidth < 720;
    }
    let sections = [
        {
            name: "Create Topic",
            route: "/ask",
            protected: true,
            logout_only: false,
        },
        {
            name: "Browse Topics",
            route: "/topics",
            protected: false,
            logout_only: false,
        },
        {
            name: "Tags",
            route: "/tags",
            protected: false,
            logout_only: false,
        },
        {
            name: "Users",
            route: "/users",
            protected: false,
            logout_only: false,
        },
        {
            name: "Profile",
            route: `/profile/${$session.user}`,
            protected: true,
            logout_only: false,
        },
        {
            name: "Register",
            route: "/register",
            protected: false,
            logout_only: true,
        },
    ];

    let activeSection = sections.find(
        (section) => "route" in section && section.route === $page.path
    );
    function pickSection(section) {
        drawerOpen = false;
        mainContent.scrollTop = 0;

        // sections.forEach((section) =>
        //  section.component.$set({ activated: false })
        // );
        // section.component.$set({ activated: true });

        activeSection =
            "shortcut" in section
                ? sections.find((sec) => sec.route === section.shortcut)
                : section;
    }
</script>

<svelte:window on:resize={setMiniWindow} />

<TopAppBar variant="static" class="demo-top-app-bar">
    <Row>
        <Section>
            {#if miniWindow}
                <IconButton
                    class="material-icons"
                    on:click={() => (drawerOpen = !drawerOpen)}
                >
                    menu
                </IconButton>
            {/if}
            <Title
                component={A}
                href="/"
                on:click={() => (activeSection = null)}
                class="mdc-theme--primary"
                style={miniWindow ? "padding-left: 0;" : ""}
            >
                Arth
            </Title>
        </Section>
        <Section align="end" toolbar>
            {#if $session.user}
                <IconButton on:click={logout} title="Log Out">
                    <Icon>
                        <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                            <path fill="#000000" d={mdiLogout} />
                        </svg>
                    </Icon>
                </IconButton>
            {:else}
                <IconButton href="/login" title="Log In">
                    <Icon>
                        <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                            <path fill="#000000" d={mdiLogin} />
                        </svg>
                    </Icon>
                </IconButton>
            {/if}
            <IconButton
                href="htts://github.com/Nalanda-Labs/arth"
                title="Source Code"
            >
                <Icon>
                    <svg style="width:24px;height:24px" viewBox="0 0 24 24">
                        <path fill="#000000" d={mdiGithub} />
                    </svg>
                </Icon>
            </IconButton>
        </Section>
    </Row>
</TopAppBar>
<div class="drawer-container">
    <Drawer {miniWindow} {sections} {drawerOpen} {pickSection} />
    {#if miniWindow}
        <Scrim />
    {/if}
    <AppContent class="app-content">
        <main
            class="main-content"
            bind:this={mainContent}
            class:mdc-elevation--z4={true}
        >
            <slot />
        </main>
    </AppContent>
</div>

如您在部分数组中所见,配置文件使用 $session.user 呈现配置文件 link。登录后 $session.user 已设置,但登录后 link 仍指向 /profile/undefined。只有在完整的页面上重新加载才会显示正确的 link。请注意,此 link 是 Drawer 组件的一部分,而不是 main 组件的一部分。 $session.userlogin.js 中设置正确,它适用于其他一切。唯一的问题是页面需要重新加载。

我最终使用以下代码完成了此操作:

onMount(async () => {
        setMiniWindow;
        const unsubscribe = session.subscribe(async ($session) => {
            if($session.user){
                sections[4].route = `/profile/${$session.user}`;
                console.log(user);
            }
        });
        return unsubscribe;
    });