【问题标题】:How do I make a component that is aware of the current url in Sapper with Svelte?如何使用 Svelte 创建一个知道 Sapper 中当前 url 的组件?
【发布时间】:2020-01-08 19:32:27
【问题描述】:

我有一个带有“Quarters”链接的导航栏的页面。在 Quarters 链接下,当用户在 /quarters 路由上时,将显示一个季度列表,如 2019Q2 等。网址将为 /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 对象,我会从服务器端代码中得到一个空引用错误。

ETA:也试过这个:

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

当用户单击其中一个数据链接时,该代码不会触发。也试过onMount,但没有阳性结果。

【问题讨论】:

    标签: svelte sapper


    【解决方案1】:

    诀窍是根据页面存储中的值创建响应式语句。

    <!--
    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>
    

    【讨论】:

      【解决方案2】:

      对于使用 SvelteKit 的人,给出的答案仍然适用。查看页面存储的文档:https://kit.svelte.dev/docs#loading-input-page

      【讨论】:

      • 你能举个例子吗?文档没用。
      • @chovy 其实我觉得他们还不错。但是在这里:以这种方式导入商店:import { page } from '$app/stores';,然后像这样使用它:{#if $page.path == '/some/route'}
      【解决方案3】:

      而不是使用afterUpdate,我相信你应该考虑用onMount 写一些东西,并使用反应性语句https://svelte.dev/examples#reactive-statements 让svelte 知道你想在位置变化时重新计算isCurrentPath

      【讨论】:

        猜你喜欢
        • 2020-02-04
        • 2019-11-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-02-13
        • 1970-01-01
        • 2019-11-24
        相关资源
        最近更新 更多