typescript - Svelte 动态多组件阵列

标签 typescript svelte

编辑:REPL 的答案 https://svelte.dev/repl/eb7616fd162a4829b14a778c3d1627e4?version=3.48.0

我所说的会呈现这个:

首先我们有一个按钮:

<button on:click={add}> Add </button>
<div id="columnflexbox">

当我点击它时,这应该会发生:

<button on:click={add}> Add </button>
<!-- This exists in DOM-->
<div id="columnflexbox">

<!-- This div and components get rendered, the Div does not exist in DOM -->
<div class="row" style="display:flex;flex-direction:row">
comp1 (instance1) 
comp2 (instance1)
</div>

当我再次单击它时,会添加另一行(带有新实例): 添加

<div id="columnflexbox">


<div class="row" style="display:flex;flex-direction:row">
comp1 (instance1) 
comp2 (instance1)
</div>
<!-- Second div is generated, it does not exist in DOM, new instances of components -->
<div class="row" style="display:flex;flex-direction:row">
comp1 (instance2)
comp2 (instance2)
</div>


</div>

有一个接口(interface):

export interface complexObject {
    comp1 : ComplexObj1
    comp2: ComplexObj2
}

let row: complexObject[] = []

添加函数:

function add(){        
    let newObj:complexObject = {
        comp1: new Comp1({target: div}), // I have to add a target here, or I get compile error, but how since the element doesn't exist?
        comp2: new Comp2({target: div})
    }

    row.push(newObj);
}

我会用这种方式来做,但我不能,因为我在没有添加目标的情况下遇到编译错误:

{#each row as rowitem }

    <div class="row">
        {rowitem.comp1}
        {rowitem.comp2}
    </div>
    
{/each}

编辑:事实证明,当我将目标添加为渲染中指定的 html 时,样式得到了正确应用:

添加函数:

function add(){    
    let div = document.createElement("div");
    div.setAttribute('class',"row")


    let newObj:complexObject = {
        comp1: new Comp1({target: div}),
        comp2: new Comp2({target: div})
    }

    row.push(newObj);
}


{#each row as rowitem }
<div class="row">
        {rowitem.comp1}
        {rowitem.comp2}
</div>    
        

{/each}

现在的问题是组件没有被渲染,我得到的是

[object Object]     [object Object]

当我尝试这样渲染时:

  <svelte:component this={rowitem.comp1}>

    </svelte:component>

我得到错误:

TypeError: l is not a constructor

如果我尝试修改 Add 函数并删除 new 关键字,我会得到:

Type 'typeof comp1__SvelteComponent_' is missing the following properties from type 'comp1__SvelteComponent_': $$prop_def, $$events_def, $$slot_def, $on, and 5 more.ts(2740)

原来这是指定接口(interface)的问题,应该这样指定:

export interface complexObject {
    comp1 : typeof ComplexObj1
    comp2: typeof ComplexObj2
}

最佳答案

为此,人们通常会使用 svelte:component它使用组件的构造函数作为输入和任何可能想要传递的 Prop 。例如

<script>
    import Comp from './Comp.svelte';
    
    let components = [
        [Comp, { content: 'Initial' }],
        [Comp, { content: 'Initial 2' }],
    ];
    function add(component, props) {
        components = [...components, [component, props]];
    }
</script>

<button type=button on:click={() => add(Comp, { content: 'Added' })}>
    Add
</button>

{#each components as [component, props]}
    <svelte:component this={component} {...props}>
        (Slotted content)
    </svelte:component>
{/each}

REPL example


类型示例:

<script lang="ts">
    import type { SvelteComponent, SvelteComponentTyped } from 'svelte';
    import Comp from './Comp.svelte';
    import Comp2 from './Comp2.svelte';
    
    let components: [typeof SvelteComponent, Record<string, any>][] = [
        [Comp, { content: 'Initial' }],
        [Comp2, { color: 'blue' }],
    ];
    function add<T extends typeof SvelteComponentTyped<P, any, any>, P>(
        component: T,
        props: P
    ) {
        components = [...components, [component, props]];
    }
</script>

add 强制组件与其 props 之间的一致性,数组不能,至少在使用元组时是这样。如果每个项目都是一个类,则该类可以强制执行其内部类型一致性。

关于typescript - Svelte 动态多组件阵列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72586711/

相关文章:

javascript - "npm run dev"命令不执行 't Work - Giving "缺少脚本 : dev"error

javascript - 预期声明 Angular 中的 SummaryPipe

javascript - 如何在 Node JS FS 模块中使用 Typescript Async/await with promise

angular - 注入(inject)器与 ViewContainerRef.injector 与 ViewContainerRef.parentInjector

javascript - Svelte:如何将 Action 传递给组件?

pouchdb - 如何修复 svelte 应用程序中的 'pouchDB not defined'

angular - 如何防止 Angular 加载组件两次?

typescript - 类型比较中的私有(private)类属性

svelte - 如何在 Svelte/Sapper 应用程序中包含 JQuery?

javascript - sveltejs 中的响应式全宽 Canvas