如何使用 Svelte 在 Sapper 中创建一个可以识别当前 url 的组件?
How do I make a component that is aware of the current url in Sapper with Svelte?
我有一个带有 "Quarters" link 导航栏的页面。在宿舍 link 下,当用户在 /quarters
路线上时,将显示宿舍列表,如 2019Q2 等。 url 将是 /quarters/2019q2
。
我想制作一个显示 hyperlink 的组件,如果当前 url 与 link。这是我能得到的最接近的:
<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
对象,我将从服务器端代码中得到一个空引用错误。
预计到达时间:也试过这个:
let isCurrentPath = false;
let path = typeof window === 'undefined' ? '' : window.location.pathname;
$: if (path) isCurrentPath = window.location.pathname.includes(link);
当用户单击其中一个数据 link 时,该代码不会触发。也尝试了 onMount
,但没有得到肯定的结果。
而不是使用 afterUpdate
我相信你应该考虑用 onMount
写一些东西并使用反应语句 https://svelte.dev/examples#reactive-statements 让 svelte 知道你想重新计算 isCurrentPath
每当位置改变时。
诀窍是根据页面存储中的值创建反应式语句。
<!--
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>
对于使用 SvelteKit 的人,给出的答案仍然适用。查看页面存储的文档:https://kit.svelte.dev/docs/modules#$app-stores
编辑:新的 SvelteKit 更新中有重大变化。您仍然可以像这样从页面存储访问当前 url:
import { page } from '$app/stores';
$page.url.pathname
我有一个带有 "Quarters" link 导航栏的页面。在宿舍 link 下,当用户在 /quarters
路线上时,将显示宿舍列表,如 2019Q2 等。 url 将是 /quarters/2019q2
。
我想制作一个显示 hyperlink 的组件,如果当前 url 与 link。这是我能得到的最接近的:
<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
对象,我将从服务器端代码中得到一个空引用错误。
预计到达时间:也试过这个:
let isCurrentPath = false;
let path = typeof window === 'undefined' ? '' : window.location.pathname;
$: if (path) isCurrentPath = window.location.pathname.includes(link);
当用户单击其中一个数据 link 时,该代码不会触发。也尝试了 onMount
,但没有得到肯定的结果。
而不是使用 afterUpdate
我相信你应该考虑用 onMount
写一些东西并使用反应语句 https://svelte.dev/examples#reactive-statements 让 svelte 知道你想重新计算 isCurrentPath
每当位置改变时。
诀窍是根据页面存储中的值创建反应式语句。
<!--
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>
对于使用 SvelteKit 的人,给出的答案仍然适用。查看页面存储的文档:https://kit.svelte.dev/docs/modules#$app-stores
编辑:新的 SvelteKit 更新中有重大变化。您仍然可以像这样从页面存储访问当前 url:
import { page } from '$app/stores';
$page.url.pathname