我正在寻找一个Svelte“委派延迟加载”组件到另一个“真实”组件。该组件对不知道存在此“代理”的用户应该是透明的:
我认为现在不可能,因为没有用于插槽转发或事件转发的api被公开。也许是通过在js中实现一个黑客,而同一个内部接口具有一个精巧的组件?
修改
我正在寻找这种魔术方法:
我有一个沉重的组件,我想异步加载
Heavy.svelte:
<div on:click>
<slot {secret}/>
<slot name="footer"/>
</div>
<script>
let secret = 'huhu';
</script>
我希望能够像这样导出该组件:
module.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”,不支持命名槽,也不支持事件。
答案 0 :(得分:0)
我能做的最好的。绑定:*不起作用,插槽和事件似乎起作用。
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>
lazy.js
import Wrapper from './Wrapper.svelte';
export function lazy(provider) {
return function(opts) {
opts.props = {...opts.props, provider };
return new Wrapper(opts)
}
}
module.js(用例示例)
import { lazy } from './lazy.js';
export let Heavy = lazy(async () => (await import("./Heavy.svelte")).Heavy);