延迟加载组件

Jér*_*e B 5 svelte svelte-3

我正在寻找一个 Svelte“委托延迟加载”组件到另一个“真实”组件。该组件对于不应该知道存在此“代理”的用户应该是透明的:

  • 延迟加载委托(使用动态导入 js 模块的回调)
  • 支持插槽(插槽应在准备好时转发给委托)
  • 支持事件(通过将订阅转发给委托)

我认为现在不可能,因为没有公开用于插槽转发或事件转发的 api。也许通过在 js 中实现相同的内部接口有一个简洁的组件来进行黑客攻击?

编辑

我正在寻找这种神奇的方法:

我有一个 Heavy 组件,我想异步加载它

重.细:

<div on:click>
  <slot {secret}/>
  <slot name="footer"/>
</div>

<script>
  let secret = 'huhu';
</script>
Run Code Online (Sandbox Code Playgroud)

我希望能够像这样导出这个组件:

模块.js

import { lazy } from './lazy.js'; // magic method

export let Heavy = lazy(async () => (await import('./Heavy.svelte')).default)
Run Code Online (Sandbox Code Playgroud)

然后,消费者可以使用 Heavy,而不知道它已被包装在这个“高阶”惰性组件中。该消费者不必处理/了解有关该包装器的异步行为的任何信息:

消费者纤细

<Heavy on:click={() => console.log("clicked")} let:secret>
  <div>{secret}</div>
  <div slot="footer">Footer</div> 
</Heavy>

<script>
  import { Heavy } from './module.js';
</script>
Run Code Online (Sandbox Code Playgroud)

我有一个“工作”解决方案,它不支持“let”,不支持命名插槽,也不支持事件。

Jér*_*e B 2

我能做的就是最好的。bind:* 不起作用,插槽和事件似乎起作用。

包装器.svelte

<svelte:component this={cpn} {...slotsProps} {...$$restProps} bind:this={instance}/>

<script>
    import { get_current_component } from 'svelte/internal';
    
    export let provider;
    
    const slotsProps = {"$$slots":$$props.$$slots, "$$scope":$$props.$$scope};
    const self = get_current_component();
    
    let cpn;
    let instance;
        
    provider().then(result => cpn = result);
    
    $: if (instance) {
        for (let [type, listeners] of Object.entries(self.$$.callbacks)) {
            instance.$on(type, (e) => {
                listeners.forEach(l => l(e));
            });
        }
    }

</script>
Run Code Online (Sandbox Code Playgroud)

懒惰.js

import Wrapper from './Wrapper.svelte';

export function lazy(provider) {
    return function(opts) {
        opts.props = {...opts.props, provider };
        return new Wrapper(opts)
    }
}
Run Code Online (Sandbox Code Playgroud)

module.js(用例示例)

import { lazy } from './lazy.js';

export let Heavy = lazy(async () => (await import("./Heavy.svelte")).Heavy);
Run Code Online (Sandbox Code Playgroud)