当从 S3 加载数据时,我应该如何构建 Sapper/Svelte 路由?
How should I structure a Sapper/Svelte route when the data is loaded from S3?
假设我有一堆数据文档,它们是 S3 中的 JSON 文档,每年一个。我通过目录结构在 Sapper 中定义了一条路线:
├── routes
│ ├── _error.svelte
│ ├── _layout.svelte
│ ├── about.svelte
│ ├── data
│ │ ├── [year].svelte
我的 script
块中的代码:
let yearData;
onMount(async () => {
const f = await fetch(yearDataUrl(year), {
headers: { 'Access-Control-Allow-Origin': '*' }
});
const jsonResults = await f.json();
yearData = jsonResults;
});
每个数据集在 S3 中为 [s3 url]/[year here].json
。导航栏中有一组链接显示每个数据集。我可以让数据以 onMount
的速度加载,但随后点击导航栏链接不会加载新数据。所以 onMount
可能是错误的选择。
我应该如何构建它?另外值得注意的是,我想在以后将这些页面呈现为静态文件(数据很少更改,尤其是前几年)。
有两种选择。第一个也是最惯用的——在你的情况下是正确的,因为听起来你想使用服务器端渲染——是使用 preload:
<script context="module">
export async function preload(page) {
const f = await this.fetch(yearDataUrl(page.params.year), {
headers: { 'Access-Control-Allow-Origin': '*' }
});
return {
yearData: await f.json()
};
}
</script>
<script>
export let yearData;
</script>
<!-- use yearData here -->
预加载函数将 运行 在创建组件之前为其提供 yearData
属性。每当 page.params
改变时,preload
将再次 运行,设置一个新的属性。
因为这在服务器和客户端上都有效(因此使用 this.fetch
而不是 fetch
,它在两种环境下都有效),您将获得服务器呈现的页面,而不是而不是在 onMount
运行 秒后闪烁到页面中的加载消息。
为了完整起见,第二个选项是使用 page store:
<script>
import { stores } from '@sapper/app';
const { page } = stores();
let yearData;
$: if (process.browser) {
fetch(yearDataUrl($page.params.year))
.then(f => f.json())
.then(data => {
yearData = data;
});
}
</script>
在这种情况下 yearData
不会 服务器呈现。 (为了完整起见,您还需要处理竞争条件和错误,这不是 preload
的问题。)
假设我有一堆数据文档,它们是 S3 中的 JSON 文档,每年一个。我通过目录结构在 Sapper 中定义了一条路线:
├── routes
│ ├── _error.svelte
│ ├── _layout.svelte
│ ├── about.svelte
│ ├── data
│ │ ├── [year].svelte
我的 script
块中的代码:
let yearData;
onMount(async () => {
const f = await fetch(yearDataUrl(year), {
headers: { 'Access-Control-Allow-Origin': '*' }
});
const jsonResults = await f.json();
yearData = jsonResults;
});
每个数据集在 S3 中为 [s3 url]/[year here].json
。导航栏中有一组链接显示每个数据集。我可以让数据以 onMount
的速度加载,但随后点击导航栏链接不会加载新数据。所以 onMount
可能是错误的选择。
我应该如何构建它?另外值得注意的是,我想在以后将这些页面呈现为静态文件(数据很少更改,尤其是前几年)。
有两种选择。第一个也是最惯用的——在你的情况下是正确的,因为听起来你想使用服务器端渲染——是使用 preload:
<script context="module">
export async function preload(page) {
const f = await this.fetch(yearDataUrl(page.params.year), {
headers: { 'Access-Control-Allow-Origin': '*' }
});
return {
yearData: await f.json()
};
}
</script>
<script>
export let yearData;
</script>
<!-- use yearData here -->
预加载函数将 运行 在创建组件之前为其提供 yearData
属性。每当 page.params
改变时,preload
将再次 运行,设置一个新的属性。
因为这在服务器和客户端上都有效(因此使用 this.fetch
而不是 fetch
,它在两种环境下都有效),您将获得服务器呈现的页面,而不是而不是在 onMount
运行 秒后闪烁到页面中的加载消息。
为了完整起见,第二个选项是使用 page store:
<script>
import { stores } from '@sapper/app';
const { page } = stores();
let yearData;
$: if (process.browser) {
fetch(yearDataUrl($page.params.year))
.then(f => f.json())
.then(data => {
yearData = data;
});
}
</script>
在这种情况下 yearData
不会 服务器呈现。 (为了完整起见,您还需要处理竞争条件和错误,这不是 preload
的问题。)