面试题答案
一键面试父子组件通信
- 父传子:
- 在父组件模板中,通过属性绑定将数据传递给子组件。例如:
<!-- 父组件 --> <script> let parentData = "Hello from parent"; </script> <ChildComponent {parentData} />
- 在子组件中,通过声明对应的属性来接收数据。例如:
<!-- 子组件 --> <script> export let parentData; </script> <p>{parentData}</p>
- 子传父:
- 在子组件中,通过
createEventDispatcher
创建一个事件分发器。例如:
<!-- 子组件 --> <script> import { createEventDispatcher } from'svelte'; const dispatch = createEventDispatcher(); function sendDataToParent() { dispatch('child - event', { data: "Hello from child" }); } </script> <button on:click={sendDataToParent}>Send data to parent</button>
- 在父组件中,通过在子组件标签上监听对应的事件来接收数据。例如:
<!-- 父组件 --> <script> function handleChildEvent(event) { console.log(event.detail.data); } </script> <ChildComponent on:child - event={handleChildEvent} />
- 在子组件中,通过
跨层级组件通信
- Context API:
- 使用
setContext
和getContext
。例如,在祖先组件中设置上下文数据:
<!-- 祖先组件 --> <script> import { setContext } from'svelte'; let sharedData = "Shared data across components"; setContext('shared - context', sharedData); </script> <SomeDescendantComponent />
- 在后代组件中获取上下文数据:
<!-- 后代组件 --> <script> import { getContext } from'svelte'; let sharedData = getContext('shared - context'); </script> <p>{sharedData}</p>
- 使用
- Store:
- 创建一个Svelte store。例如:
// store.js import { writable } from'svelte/store'; export const sharedStore = writable("Initial value");
- 在任何组件中导入并使用该store。例如:
<!-- 组件1 --> <script> import { sharedStore } from './store.js'; function updateStore() { sharedStore.update((value) => value + " updated"); } </script> <button on:click={updateStore}>Update store</button>
<!-- 组件2 --> <script> import { sharedStore } from './store.js'; let value; $: sharedStore.subscribe((newValue) => { value = newValue; }); </script> <p>{value}</p>
避免数据传递冗余和性能问题
- 数据流动优化:
- 尽量保持单向数据流,明确数据的来源和流向,减少不必要的数据传递。例如,对于父子组件通信,确保子组件只接收它实际需要的数据,避免传递过多无关数据。
- Memoization:
- 使用Svelte的
$:
语句进行自动响应式更新。如果一个值是基于其他响应式数据计算得出的,可以使用$:
将其定义为派生值,Svelte会自动跟踪依赖并仅在依赖变化时重新计算。例如:
<script> let a = 1; let b = 2; $: sum = a + b; </script> <p>The sum of a and b is {sum}</p>
- 对于函数计算,可以使用
$:
配合memo
(虽然Svelte没有内置memo
,但可以自己实现类似功能)来避免不必要的重复计算。例如:
<script> let data1 = [1, 2, 3]; let data2 = [4, 5, 6]; let memoizedResult; $: { if (!memoizedResult || data1.length!== memoizedData1.length || data2.length!== memoizedData2.length) { memoizedData1 = data1.slice(); memoizedData2 = data2.slice(); memoizedResult = data1.concat(data2); } } </script>
- 使用Svelte的
- Lazy Loading:
- 对于多层嵌套组件中一些不常用的组件,可以使用动态导入(
{#await}
块)进行懒加载。例如:
<script> const loadComponent = async () => { const { SomeHeavyComponent } = await import('./SomeHeavyComponent.svelte'); return SomeHeavyComponent; }; let promise = loadComponent(); </script> {#await promise} <p>Loading...</p> {:then SomeHeavyComponent} <SomeHeavyComponent /> {:catch error} <p>{error.message}</p> {/await}
- 这样可以避免在应用启动时加载所有组件,从而提高性能。
- 对于多层嵌套组件中一些不常用的组件,可以使用动态导入(