嵌套组件在 Svelte/Sapper 中无法正确呈现

Nested component does not render properly in Svelte/Sapper

我在 slug 中有三个文件。我使用 slug 参数作为目录名称。 我遇到的问题是除了 taglist 中的每个循环之外的所有问题。由于某种原因,它没有收到道具 tagList。任何帮助将不胜感激。

index.svelte

<script context="module">
    export function preload({ params }, { user }) {
        let [id, slug] = [params.id, params.slug];
        return { id, slug };
    }
</script>

<script>
    import Editor from "../../../_components/Editor.svelte";
    import Topics from "./Topics.svelte";
    import { stores } from "@sapper/app";

    export let id;
    export let slug;

    const { session } = stores();
</script>

<svelte:head>
    <title />
</svelte:head>

<div class="editor-page">
    <div class="container page">
        <div class="row">
            <div class="col-md-8 offset-md-2 col-xs-12">
                <Topics {id} {slug} />
                {#if $session.user}
                    <Editor />
                {/if}
            </div>
        </div>
    </div>
</div>

Topics.svelte

<script>
    import { onMount } from "svelte";
    import * as api from "api.js";
    import "bytemd/dist/index.min.css";
    import TagList from "../../../_components/_TagList.svelte";

    export let id;
    export let slug;

    let topics = [];
    let title = "";
    let tagList = [];
    let value = "";
    let Viewer = null;

    onMount(async () => {
        const bytemd = await import("bytemd");
        Viewer = bytemd.Viewer;

        const response = await api.get(
            `t/${id}/${slug}`,
            localStorage.getItem("jwt")
        );

        console.log(response);

        if (response.topic) {
            topics = response.topic;
            title = response.title;            
            value = topics[0].description;
            for(let i= 0; i < response.tags.length; i++) {
                tagList.push(response.tags[i]);
            }
        }
    });
</script>

<div>
    <h3>{title}</h3>
    <hr/>
    <svelte:component this={Viewer} {value} />
    <TagList {tagList} />
</div>

_TagList.svelte

<script>
    export let tagList;

    console.log(tagList);
</script>

<ul>
    {#each tagList as tag}
        <p>hello</p>
        <li>{tag.name}</li>
    {/each}
</ul>

在 Svelte 中,更新仅通过分配触发。

在您的情况下,这意味着当呈现组件时,它将呈现一个空的标签列表 (tagList = [])。

现在在 onMount 中您执行 taglist.push,但如前所述,这不会触发更新(请记住此函数在 after 后调用该组件已安装)因为它不是一个分配。

有四种方法可以解决您的问题:

  1. 在执行 for 循环后 tagList = tagList,这是一个赋值,将触发更新。
  2. 不要执行 for 循环,而是使用映射 tagList = response.tags.map(tag => tag)
  3. 不是执行 for 循环,而是将标签分散到标签列表中 tagList = [...response.tags]
  4. 考虑到你无论如何都不对标签做任何事情,而且 tagList 是空的而且你似乎没有任何其他更新方式,直接将标签分配给它tagList = response.tags

当然你的代码可能会被简化,如果你在将每个标签添加到列表之前实际对它做一些事情,情况 3 和 4 不是好的选择,对于那种情况我会使用 map 选项