简体   繁体   English

Sveltekit:使用 $page.path 设置活动链接的样式

[英]Sveltekit: Styling active links with $page.path

I'm working on a sveltekit app with a sidenav containing links.我正在开发一个带有包含链接的 sidenav 的 sveltekit 应用程序。 I can't get the active class styling on my links to work properly.我无法使链接上的活动 class 样式正常工作。

The links are components in NavLink.svelte :链接是NavLink.svelte中的组件:

<script>
  import { page } from '$app/stores';
  import Icon from '$lib/Icon.svelte';
  export let title;
  export let href;
</script>

<a {href} class="link" class:active={$page.path == href}>
  <Icon {title} />
</a>

<style>
a.active {
  background-color: rgba(0,0,0,0.24);
</style>

These links are used in SideNav.svelte :这些链接在SideNav.svelte中使用:

<script>
  import NavLink from '$lib/NavLink.svelte';
</script>

<nav class="container">
  <div id="links">
    <NavLink href="/link1" title="icon1" />
    <NavLink href="/link2" title="icon2" />
    <NavLink href="/link3" title="icon3" />
  </div>
</nav>

And finally, the sidenav is loaded in my __layout.svelte :最后,sidenav 加载到我的__layout.svelte中:

<SideNav />
<slot />
<Footer />

Now when I click one of my sidenav links, I am routed to the proper page but my NavLink is not styled with the .active class. If I inspect the link, however, devtools shows me this: <a class="link active:true"> and the other links have active:false .现在,当我单击其中一个 sidenav 链接时,我被路由到正确的页面,但我的 NavLink 没有使用.active class 设置样式。但是,如果我检查该链接,devtools 会向我显示: <a class="link active:true">和其他链接有active:false

So it looks like the function is working, but my active style is not applied (the background color).所以看起来 function 正在工作,但我的活动样式没有应用(背景颜色)。 What am I missing?我错过了什么?

I tried moving the Active class code to the SideNav component instead of the NavLink component and observed the same behavior.我尝试将 Active class 代码移动到 SideNav 组件而不是 NavLink 组件并观察到相同的行为。 I could not figure it out, so I found a new method that works just fine.我无法弄清楚,所以我找到了一种效果很好的新方法。

In my NavLink.svelte :在我的NavLink.svelte中:

<script>
  import {onMount} from "svelte";
  import Icon from '$lib/Icon.svelte';

  let currentPath;
  onMount(() => {
    currentPath = window.location.pathname;
  });
  export let title;
  export let href;
</script>

<a {href} class:active={currentPath == href}>
  <Icon {title} />
</a>

And the rest of the code is the same.和密码的rest是一样的。 Now my links get the proper styling.现在我的链接获得了正确的样式。 It's worth noting that they simply have <a class="active"> and not <a class="active:true"> .值得注意的是,它们只有<a class="active">而不是<a class="active:true"> Why wasn't it working with the other method?为什么它不能与其他方法一起使用?

To achieve this in the latest version of SvelteKit, after the introduction of some breaking changes, you can do:要在最新版本的 SvelteKit 中实现这一点,在引入一些重大更改后,您可以执行以下操作:

<a {href} class:active={$page.url.pathname === href}>

$page.url returns something like: $page.url返回如下内容:

URL { 
    href: "http://localhost:5173/accounts/login", 
    origin: "http://localhost:5173", 
    protocol: "HTTP:", 
    username: "", 
    password: "", 
    host: "localhost:5173", 
    hostname: "localhost", 
    port: "5173", 
    pathname: "/accounts/login", 
    search: "" 
}

You can then compare $page.url.pathname with the href of the anchor tag.然后,您可以将$page.url.pathname与锚标记的href进行比较。

I figured it out.... I think I just forgot to include quotes.我想通了....我想我只是忘了加上引号。 D'oh.哦。 Working code (that also accounts for sub-pages) for the NavLink is: NavLink 的工作代码(也包含子页面)是:

<a {href} class:active="{$page.path.includes(href)}">

Here is my solution to only match the first segment of the current URL:这是我的解决方案,只匹配当前 URL 的第一段:

<a
  class:active={$page.url.pathname.split("/")[1] ===item.href.split("/")[1]}
  href={item.href}>
  {item.label}
</a>
  a.active {
   background-color:red;
  }

You might want to use $page.route.id which contains the route id only, even if you have params in the path.您可能想使用仅包含路由 ID 的$page.route.id ,即使路径中有参数也是如此。

Example, the path /catalogue/123 will gives:例如,路径/catalogue/123将给出:

  • $page.url.pathname === /catalogue/123 (different for each item, does not work everywhere) $page.url.pathname === /catalogue/123 (每个项目不同,不是到处都有效)
  • $page.route.id === /catalogue/[id] (same for all items) $page.route.id === /catalogue/[id] (所有项目都相同)

Then you can use in your links:然后你可以在你的链接中使用:

<a href="/catalogue/123" class:active={$page.route.id === '/catalogue/[id]'}>catalogue</a>

Inn the end this will work for static links (/catalogue) and dynamic links (/catalogue/456).最后,这将适用于 static 链接 (/catalogue) 和动态链接 (/catalogue/456)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM