sveltekit 路线更改时如何关闭下拉菜单?

How can I close my dropdown menu when sveltekit route changes?

我有一个 <SideBar /> 组件,onDestroy() 似乎不会在路由更改时触发。

我需要在路线改变时关闭菜单,否则菜单会保持打开状态,这是一个糟糕的用户体验。

<script>
    import { page } from '$app/stores';
    import { onDestroy } from 'svelte';
    let isMainNavOpen = true;
    let isGroupNavOpen = false;
    function toggleGroupMenu(e) {
        e.preventDefault();

        isGroupNavOpen = !isGroupNavOpen;
    }

    $: currentPath = $page.url.pathname;
</script>

    <nav>
        <header class="groups" class:closed={!isGroupNavOpen}>
            <div class="dropdown">
                <a href="#" class="toggler" on:click|preventDefault={toggleGroupMenu}>
                    <img src="/icons/chevron.svg" alt="" border="0" />
                </a>
                <ul>
                    {#each groupMenu as item, i}
                        <li class:active={currentPath === item.path}>
                            <a href="/groups/{item.id}"
                                ><img
                                    class="avatar"
                                    src="/icons/avatar.group.png"
                                    alt=""
                                    border="0"
                                />{item.name}</a
                            >
                        </li>
                    {/each}
                </ul>
                <a href="/groups" class="button secondary outlined">Explore Groups</a>
            </div>
        </header>
    </nav>

<style>
    nav {
        padding: 1.2rem;
        flex-grow: 1;
        display: flex;
        flex-direction: column;
    }

    nav header {
        color: #fff;
        display: flex;
        flex-direction: column;
    }

    .groups.closed li:not(:first-child) {
        display: none;
    }

    .groups .toggler {
        position: absolute;
        top: 2.5rem;
        right: 1rem;
        margin-left: 1.4rem;
    }

    .groups .toggler img {
        transform: rotate(180deg);
    }

    .groups.closed .toggler img {
        transform: rotate(0deg);
    }

    .groups ul {
        width: 100%;
        max-height: 22rem;
        overflow-y: auto;
        background-color: #060536;
        color: #fff;
        border-radius: 0.8rem;
    }

    .groups ul .active {
        background-color: #34326d;
    }

    .groups .dropdown {
        width: 100%;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 1;
        background-color: #060536;
    }

    header.groups {
        padding: 0;
        position: relative;
        overflow: visible;
    }

    .groups .avatar {
        width: 5rem;
        display: block;
        margin-right: 1.4rem;
    }

    .groups li {
        display: flex;
        justify-content: space-between;
        align-items: center;
    }

    .groups li a {
        padding: 1rem;
        display: flex;
        justify-content: flex-start;
        align-items: center;
        flex-grow: 1;
        color: #fff;
        text-decoration: none;
        font-weight: 600;
        word-break: break-all;
    }

    .groups .button {
        font-weight: 600;
        font-size: 1.4rem;
        width: 80%;
        margin: 1rem auto;
    }

    .groups.closed .button {
        display: none;
    }

    nav ul {
        display: flex;
        flex-direction: column;
    }

    nav ul {
        list-style-type: none;
        padding: 0;
        margin: 0;
        flex: 1;
    }
</style>

我可能还需要一个底衬,如果他们点击关闭菜单,它也会关闭。

我假设您将此边栏添加到布局页面的某处,这意味着在页面更改时此组件不会被破坏,它保持不变(除非您移动到具有不同布局的页面)。在 SvelteKit 中,导航仅更改 <slot> 中的部分,而不更改其余部分。

您可以通过简单地响应页面更改来解决此问题:

$: $page.url && (isGroupNavOpen = false)

我使用setTimeout来切换菜单内容的style display property,点击后关闭菜单内容:

<script>
  ...
  let display = "";  // Svelte style property
  ...
</script>


<div class="nav-menu">
  <div class:active class="menu-btn">
    <span>{text}</span>
    <i class="fa fa-caret-down" />
  </div>
  <div
    class="menu-content"
    style:display
    on:click={() => {
      display = "none";
      setTimeout(() => (display = ""), 0);
    }}>
    <slot />
  </div>
</div>

更新:
删除了 on:click.
中的 stopPropagation Sveltekit filesystem-based 路由器需要点击一下!

在响应式语句中使用 svelte-kit 中的“导航”商店

$: if($navigating) //代码;