- 使用
bind:this
和 createEventDispatcher
控制更新范围
- 首先,Svelte 中的
createEventDispatcher
可以用于创建一个事件分发器,通过它可以触发自定义事件。bind:this
可以获取组件实例,以便在父组件中直接操作子组件。
- 假设我们有如下组件结构:
App.svelte
-> Parent.svelte
-> Child.svelte
-> DeepChild.svelte
,DeepChild.svelte
是数据更新频繁的组件。
- DeepChild.svelte:
<script>
import { createEventDispatcher } from'svelte';
const dispatch = createEventDispatcher();
let data = 0;
function updateData() {
data++;
dispatch('data - updated', { value: data });
}
</script>
<button on:click={updateData}>Update Data</button>
<script>
import DeepChild from './DeepChild.svelte';
let deepChild;
function handleDataUpdate(event) {
// 在这里可以处理数据,并且只通知必要的上层组件
deepChild = event.detail.value;
}
</script>
<DeepChild bind:this={deepChild} on:data - updated={handleDataUpdate} />
<script>
import Child from './Child.svelte';
let childData;
function handleChildDataUpdate(event) {
childData = event.detail.value;
}
</script>
<Child on:data - updated={handleChildDataUpdate} />
<script>
import Parent from './Parent.svelte';
</script>
<Parent />
- 使用
$$props
和 $$restProps
优化更新
- Svelte 中的
$$props
包含了所有传递给组件的属性,$$restProps
包含了除了在组件脚本中显式声明的属性之外的其他属性。
- 假设在
DeepChild.svelte
中,我们只关心某些特定属性的变化。
- DeepChild.svelte:
<script>
let { specificProp } = $$props;
function updateBasedOnProp() {
// 只在 specificProp 变化时进行相关操作
}
</script>
- 这样,当其他不相关的属性在父组件更新时,
DeepChild.svelte
不会因为这些无关属性的变化而重新渲染,从而实现细粒度控制。
- 使用
{#if}
和 {#await}
条件渲染
- 在父组件中,如果某些情况下不需要渲染深层组件,可以使用
{#if}
来控制。
- Parent.svelte:
<script>
import Child from './Child.svelte';
let shouldRenderChild = true;
function toggleRender() {
shouldRenderChild =!shouldRenderChild;
}
</script>
<button on:click={toggleRender}>Toggle Child Render</button>
{#if shouldRenderChild}
<Child />
{/if}
- 如果深层组件依赖异步数据,使用
{#await}
可以在数据加载完成后才渲染组件,避免在数据未准备好时不必要的更新。
- Child.svelte:
<script>
import { onMount } from'svelte';
let asyncData;
onMount(async () => {
const response = await fetch('/api/data');
asyncData = await response.json();
});
</script>
{#await asyncData}
<p>Loading...</p>
{:then data}
<DeepChild {data} />
{:catch error}
<p>Error: {error.message}</p>
{/await}