延迟加载组件

Posted

技术标签:

【中文标题】延迟加载组件【英文标题】:Lazy Loading Component 【发布时间】:2020-10-17 18:57:16 【问题描述】:

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

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

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

编辑

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

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

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”,不支持命名插槽,也不支持事件..

【问题讨论】:

能否请您准确说明您期望的界面和行为?举个使用例子,比如 @illright 我已经用你的建议更新了我的问题。任何想法 ? :) 【参考方案1】:

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

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);

【讨论】:

以上是关于延迟加载组件的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法检查延迟加载的组件(使用 React.Lazy)是不是已完成加载?

角度 5 延迟加载与动态加载

Laravel 从 vue 文件中混合延迟加载组件

为函数而不是组件反应延迟加载

Angular 9 嵌套延迟加载模块,带有嵌套路由器出口

使用 Webpack 2 延迟加载 Vue 组件