【问题标题】:How context="module" works in Svelte and Sapper?context="module" 如何在 Svelte 和 Sapper 中工作?
【发布时间】:2020-09-22 21:23:35
【问题描述】:

当我从服务器获取数据时使用 Sapper 构建项目时,预加载函数在脚本 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>

【问题讨论】:

  • AFAIK,不像onMount 每个组件实例调用一次,context="module" 脚本只执行一次。

标签: svelte sapper


【解决方案1】:

考虑一个导出类的常规 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 术语来表达:

  • “评估模块”代码是发生在&lt;script context="module"&gt; 中的代码
  • “实例化组件”代码等同于常规 &lt;script&gt; 标记中发生的代码

【讨论】:

    【解决方案2】:

    是的,确实如此,尽管有一点点区别:context="module" 调用是在创建组件之前执行的。

    引用official docs

    它在组件创建之前运行

    这对于产品列表之类的情况很有用...您不知道要显示哪些产品,因此您可以获取数据并为结果中的每个项目实例化一个产品组件。

    【讨论】:

      【解决方案3】:

      在使用 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/

      【讨论】:

        猜你喜欢
        • 2019-11-24
        • 2020-02-19
        • 2020-04-09
        • 2020-09-04
        • 2021-07-14
        • 1970-01-01
        • 1970-01-01
        • 2021-04-12
        • 2020-02-04
        相关资源
        最近更新 更多