Svelte:通过组件构造函数传递reactive prop的最佳方式?
通过构造函数实例化Svelte组件并保留响应性的最佳实践
当用组件标签<Component/>时,Svelte会自动建立props的响应式绑定,但通过new Component()构造函数实例化时,初始props是一次性传递的,不会自动监听状态变化。以下是两种实用的解决方法:
方法一:反应式语句手动更新props
核心逻辑是保存组件实例,用Svelte的反应式声明监听状态变化,调用组件实例的$set方法更新props。
修改后的App.svelte:
<script> import { onMount } from 'svelte'; import Component from './Component.svelte'; let componentContainer; let enabled = false; let componentInstance; onMount(() => { // 创建组件时保存实例引用 componentInstance = new Component({ target: componentContainer, props: { enabled }, }); }); // 监听enabled变化,自动同步到组件 $: if (componentInstance) { componentInstance.$set({ enabled }); } </script> <h1>Component</h1> <form> <label> <input type="checkbox" bind:checked={enabled}> Enabled </label> </form> <hr> <p>Using tag...</p> <Component {enabled}/> <hr> <p>Using constructor...</p> <div bind:this={componentContainer}></div>
Component.svelte保持原代码即可。这种方法简单直接,适合单个组件的响应式需求。
方法二:用Svelte Store共享状态
如果需要跨组件共享状态,用Store更优雅——组件内部订阅Store后会自动响应变化,无需手动维护props更新。
- 创建
stores.js:
import { writable } from 'svelte/store'; export const enabledStore = writable(false);
- 修改Component.svelte:
<script> import { enabledStore } from './stores.js'; </script> {#if $enabledStore} <p>I'm enabled!</p> {/if}
- 修改App.svelte:
<script> import { onMount } from 'svelte'; import Component from './Component.svelte'; import { enabledStore } from './stores.js'; let componentContainer; let enabled = false; // 同步本地勾选状态到Store $: enabledStore.set(enabled); onMount(() => { new Component({ target: componentContainer, // 无需传props,组件直接订阅Store }); }); </script> <h1>Component</h1> <form> <label> <input type="checkbox" bind:checked={enabled}> Enabled </label> </form> <hr> <p>Using tag...</p> <Component /> <!-- 标签用法也无需传props --> <hr> <p>Using constructor...</p> <div bind:this={componentContainer}></div>
这种方法适合多组件共享状态的场景,能大幅减少手动维护响应式的代码量。
内容的提问来源于stack exchange,提问作者thdoan
相关产品推荐
相关产品推荐

