如何在Sapper with Svelte中制作一个能够识别当前URL的组件?

15

我有一个页面,其中带有“Quarters”链接的导航栏。在“Quarters”链接下,当用户处于/quarters路由时,将显示季度列表,例如2019Q2等。URL将为/quarters/2019q2

我想制作一个组件,它会显示超链接,如果当前URL与链接的href匹配,则会有selected类。以下是我能够接近的最近代码:

<script>
  import { afterUpdate } from 'svelte';
  export let segment;
  export let text = 'text here';
  export let link;
  let isCurrentPath = false;
  console.log(segment, link, text);
  afterUpdate(() => {
    if (window.location.pathname.includes(link)) {
      isCurrentPath = true;
      debugger;
    }
    console.log('HL afterUpdate ', window.location);
  });
</script>

<style>
  /* omitted */
</style>

<a class:selected={segment && isCurrentPath} href={link}>{text}</a>

对于首次加载,这很好,但当用户导航到不同的数据页面时,选择不会更新。如何使某些代码仅在客户端运行?如果我在afterUpdate之外访问window对象,我将从服务器端代码获得null引用错误。

预计完成时间:我也尝试过这个:

  let isCurrentPath = false;
  let path = typeof window === 'undefined' ? '' : window.location.pathname;
  $: if (path) isCurrentPath = window.location.pathname.includes(link);

当用户单击数据链接时,该代码不触发。尝试使用onMount,但结果并不理想。

3个回答

12

关键是基于页面存储中的值创建一个反应性语句。

<!--
This is used to have a link on the page that will show highlighted if the url meets the criteria.
You might want to adjust the logic on line 19.
usage: 
<HighlightedLink bind:segment highlight="faq" rel="prefetch" link="/faq" text="FAQ" />
--> 

<script>
  import { stores } from '@sapper/app';
  const { page } = stores();
  export let highlight;
  export let segment;
  export let text = 'text here';
  export let link;
  export let target;
  let highlightPath = false;
  $: highlightPath =
    $page.path && highlight && ($page.path.includes(highlight) || $page.path.includes(link));
</script>

<style>
  .selected {
    position: relative;
    display: inline-block;
  }
  .selected::after {
    position: absolute;
    content: '';
    width: calc(100% - 1em);
    height: 2px;
    background-color: rgb(255, 62, 0);
    display: block;
    bottom: -1px;
  }
  a {
    padding-left: 10px;
  }
</style>


<a class:selected={highlightPath} href={link}>{text}</a>

9
对于使用 SvelteKit 的人,给出的答案仍然适用。查看页面 store 的文档:https://kit.svelte.dev/docs/modules#$app-stores-page 编辑:新的 SvelteKit 更新中存在破坏性更改。您仍然可以像这样从页面 store 访问当前 url:
import { page } from '$app/stores';
$page.url.pathname

3
你能提供一个例子吗?文档没什么用。 - chovy
2
@chovy 其实我认为它们相当不错。但是这里有一个例子: 以这种方式导入 store:import { page } from '$app/stores'; 然后像这样使用它:{#if $page.path == '/some/route'} - m1212e

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接