context="module" 如何在 Svelte 和 Sapper 中工作?
How context="module" works in Svelte and Sapper?
当我使用 Sapper 构建项目时,每当我从服务器获取数据时,preload 函数是在脚本 context="module" 内声明的,如下所示。
<script context="module">
export async function preload(page) {
return await this.fetch(`https://reqres.in/api/users?page=1`)
.then(res1 => {
return res1.json()
}).then(res2 => {
return {
notices: res2.data,
}
})
}
</script>
根据 document
A <script> tag with a context="module" attribute runs once when the module first evaluates, rather than for each component instance.
但是模块第一次求值时是什么意思?
是指组件第一次渲染的时候吗?那么在 onMount 生命周期方法中声明 api fetch 函数是不是和下面的代码一样?
<script>
onMount(async() => {
const res = await fetch(`https://reqres.in/api/users?page=1`);
const json = await res.json();
})
</script>
是的,确实如此,尽管存在细微差别:context="module"
调用是在创建组件之前执行的。
it runs before the component is created
这对于产品列表等情况很有用...您不知道要显示哪些产品,因此您获取数据并为结果中的每个项目实例化一个产品组件。
考虑导出 class:
的常规 JavaScript 模块
// Component.js
console.log('evaluating module');
export class Component {
constructor() {
console.log('instantiating component');
}
}
如果将该模块导入您的应用程序,该代码将立即 运行:
import { Component } from './Component.js';
// "evaluating module" has already been logged. This will only happen once
// for the entire application, however many modules import Component.js
const component1 = new Component(); // logs "instantiating component"
const component2 = new Component(); // logs "instantiating component" again
现在我们可以用 Svelte 术语来表达它了:
- 'evaluating module' 代码是
<script context="module">
中发生的事情
- 'instantiating component' 代码等同于常规
<script>
标签中发生的事情
当使用 Sapper 或 SvelteKit(相当于 react 世界中的 Next.js)时,SSR 组件无法直接在标签中访问 window 对象,因此您需要等到该组件是“水合的”,或传统上呈现的。这意味着任何使用 window 的库,实际上任何需要在浏览器中 运行 的东西都必须通过 onMount
完成
使用 SSR 时,借助 SvelteKit 等工具,onMount() 不会在服务器上 运行。因此,您的客户端相关代码(例如本地存储访问)可以放在 onMount() 中,它不会抛出服务器错误。
来自 https://www.reddit.com/r/sveltejs/comments/p5p386/trying_to_understand_script_vs_onmount/
当我使用 Sapper 构建项目时,每当我从服务器获取数据时,preload 函数是在脚本 context="module" 内声明的,如下所示。
<script context="module">
export async function preload(page) {
return await this.fetch(`https://reqres.in/api/users?page=1`)
.then(res1 => {
return res1.json()
}).then(res2 => {
return {
notices: res2.data,
}
})
}
</script>
根据 document
A <script> tag with a context="module" attribute runs once when the module first evaluates, rather than for each component instance.
但是模块第一次求值时是什么意思?
是指组件第一次渲染的时候吗?那么在 onMount 生命周期方法中声明 api fetch 函数是不是和下面的代码一样?
<script>
onMount(async() => {
const res = await fetch(`https://reqres.in/api/users?page=1`);
const json = await res.json();
})
</script>
是的,确实如此,尽管存在细微差别:context="module"
调用是在创建组件之前执行的。
it runs before the component is created
这对于产品列表等情况很有用...您不知道要显示哪些产品,因此您获取数据并为结果中的每个项目实例化一个产品组件。
考虑导出 class:
的常规 JavaScript 模块// Component.js
console.log('evaluating module');
export class Component {
constructor() {
console.log('instantiating component');
}
}
如果将该模块导入您的应用程序,该代码将立即 运行:
import { Component } from './Component.js';
// "evaluating module" has already been logged. This will only happen once
// for the entire application, however many modules import Component.js
const component1 = new Component(); // logs "instantiating component"
const component2 = new Component(); // logs "instantiating component" again
现在我们可以用 Svelte 术语来表达它了:
- 'evaluating module' 代码是
<script context="module">
中发生的事情
- 'instantiating component' 代码等同于常规
<script>
标签中发生的事情
当使用 Sapper 或 SvelteKit(相当于 react 世界中的 Next.js)时,SSR 组件无法直接在标签中访问 window 对象,因此您需要等到该组件是“水合的”,或传统上呈现的。这意味着任何使用 window 的库,实际上任何需要在浏览器中 运行 的东西都必须通过 onMount
完成使用 SSR 时,借助 SvelteKit 等工具,onMount() 不会在服务器上 运行。因此,您的客户端相关代码(例如本地存储访问)可以放在 onMount() 中,它不会抛出服务器错误。
来自 https://www.reddit.com/r/sveltejs/comments/p5p386/trying_to_understand_script_vs_onmount/