Sveltekit + Vite - 当使用它的文件未修改时,存储无法正确反应

问题描述 投票:0回答:1

我真的不知道问题是什么,但情况是这样的:

我有一个自定义存储,其中包含一个从 API 获取数据的数组。在我的主 +page.svelte 文件中,我在

onMount()
中初始化此商店并显示其内容。

这完全按照预期工作 - 我的数据出现在页面上 - 但是,一旦我重新加载页面或编译/保存,它就好像我的存储为空(没有错误消息,但也没有数据)。记录我商店的内容显示一个空数组 (

Array []
),但它填充了内容: Array empty but filled

但是,一旦我修改此 +page.svelte(即使只是在

script
标签内部或外部添加注释),我的数据就会出现。记录后,它确实正确显示了一个填充的数组(
Array(3) [ {...}, {...}, {...} ]
): Array filled
编辑:修改其子组件或 +layout.svelte 组件不会破坏商店,但是当破坏时它不会修复它。

基本上,无论我在做什么,如果我不修改这个主页,它的行为就不会正确。

我的项目是使用 sveltekit bootstrap

npm create svelte@latest
选择 typescript、eslint 和 prettier 创建的,并且我添加了 SCSS。我一直在控制台中看到“vite”,所以我猜它也在那里?

我处于开发模式(我运行了

npm run dev
),一切正常,没有任何编译问题。

我已经尝试过查看一些配置文件,但老实说我什么都不明白。

同样,我已经尝试过在互联网上查找,但由于我无法真正定义问题,所以有点困难。

有人 IRL(作为 C 开发人员工作,所以他们无能为力)建议这是一个编译器问题,但真的是这样吗?如果是这样,我可以做些什么吗?

我不得不提的是,除了基本脚本之外,我真的不知道任何技术,所以请 ELI5。

+page.svelte

<script lang="ts">
import { onMount } from "svelte";
import { meals } from "../store/meals";
import MealCard from "./MealCard.svelte";

onMount( () => {
    meals.initialise();
});
</script>

<h1>Today's Selection</h1>
<div class="list">
    {#each $meals as meal}
        <MealCard meal={meal}/>
    {/each}
</div>

meal.ts
(商店)- 为了清楚起见,输入“remove”

import { writable } from "svelte/store";

function createMeals() {
    const meals = [{
        id: "",
        name: "",
        preview: "",
        ingredients: [],
        tags: [],
        category: "",
        origin: "",
        source: "",
        video: "",
        instructions: "",
        locked: false
    }];

    const nbOfMeals = 3;
    
    const {subscribe} = writable(meals);
    
    return {
        subscribe,
        add: (meal) => {
            meals.push(meal);
        },

        initialise: async () => {
            if (meals.length === nbOfMeals) {
                return;
            }
            for (let iMeal = 0; iMeal < nbOfMeals; iMeal++) {
                getMeal();
            }
            meals.shift();
        }
    }
}

export const meals = createMeals();

async function getMeal() {
    const meal = {
        id: "1",
        name: "",
        preview: "",
        ingredients: [""],
        tags: [],
        category: "",
        origin: "",
        source: "",
        video: "",
        instructions: "",
        locked: false,
    };
    const url = "https://www.themealdb.com/api/json/v1/1/random.php";

    await fetch(url)
    .then((response) => response.json())
    .then((data) => {
        const _data = data.meals[0];

        meal.id = _data.idMeal;
        meal.name = _data.strMeal;
        meal.preview = _data.strMealThumb;
        
        const tags = _data.strTags;
        if (tags) {
            meal.tags = tags.split(",");
        }
        
        meal.category = _data.strCategory;
        meal.origin = _data.strArea;
        meal.source = _data.strSource;
        meal.video = _data.strYoutube;
        meal.instructions = _data.strInstructions;

        meal.ingredients = [""];
        
        let iIngr = 1;
        while (_data["strIngredient" + iIngr]) {
            let toAdd;
            const regexp = /\d|¼|½|¾|(\w+ of)/;

            if (regexp.test(_data["strMeasure" + iIngr])) {
            toAdd =
            _data["strMeasure" + iIngr] +
                " " +
                _data["strIngredient" + iIngr];
            } 

            else if (/[^\w]/.test(_data["strMeasure" + iIngr])) {
            toAdd = _data["strIngredient" + iIngr];
            } 

            else {
            toAdd =
            _data["strIngredient" + iIngr] +
                " (" +
                _data["strMeasure" + iIngr].toLowerCase() +
                ")";
            }

            meal.ingredients.push(toAdd);
            iIngr++;
        }
        meal.ingredients.shift();
        meals.add(meal);
    });
}
vite svelte sveltekit
1个回答
0
投票

[...]一旦我重新加载页面或编译/保存,它就好像我的商店是空的[...]

这可能是由于服务器端渲染造成的。当您的 Web 浏览器首次显示页面/重新加载页面时,您的 Svelte 应用程序将在服务器上运行,并且服务器会发回为其生成的 HTML 代码。此后,Web 浏览器将开始运行您的 Svelte 应用程序本身(如果在 Web 浏览器中启用了客户端 JS)。

服务器将在您的商店完全加载之前发回页面的 HTML 代码。在

onMount()
中,您调用
meals.initialize()
,但在服务器上,永远不会调用
onMount()
。即使是这样,您也需要在
await
中的
getMeal()
上使用
initialize()
(但是您可能还想使用 Promise.all(),因此您同时运行所有承诺时间)。

您能确认这是您遇到的问题吗?如果这不是问题,不想浪费时间建议不同的解决方案^^

getMeal()
中,如果您使用
then()
,则不应使用
catch()
/
await
,而应使用
try
catch

© www.soinside.com 2019 - 2024. All rights reserved.