延迟加载组件



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

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

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

编辑

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

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

Heavy.svelte:

<div on:click>
<slot {secret}/>
<slot name="footer"/>
</div>
<script>
let secret = 'huhu';
</script>

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

模块.js

import { lazy } from './lazy.js'; // magic method
export let Heavy = lazy(async () => (await import('./Heavy.svelte')).default)

然后,使用者可以使用 Heavy,而不知道它已被包装在这个"高阶"惰性组件中。 这个消费者不必处理/知道这个包装器的异步行为:

Consumer.svelte

<Heavy on:click={() => console.log("clicked")} let:secret>
<div>{secret}</div>
<div slot="footer">Footer</div> 
</Heavy>
<script>
import { Heavy } from './module.js';
</script>

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

我能做的最好的事情。 绑定:* 不起作用,插槽和事件似乎有效。

Wrapper.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>

懒惰.js

import Wrapper from './Wrapper.svelte';
export function lazy(provider) {
return function(opts) {
opts.props = {...opts.props, provider };
return new Wrapper(opts)
}
}

模块.js(用例示例(

import { lazy } from './lazy.js';
export let Heavy = lazy(async () => (await import("./Heavy.svelte")).Heavy);

最新更新