面试题答案
一键面试原理
- Svelte 响应式系统基础:Svelte 通过跟踪变量的赋值操作来自动更新 DOM。当一个变量被赋值时,Svelte 会检查哪些 DOM 元素依赖于这个变量,并自动更新它们。
- 上下文 API 与响应式:通过
setContext
和getContext
传递的数据,本身并不会自动触发响应式更新。但是,如果传递的数据是一个可响应的对象(即 Svelte 中的$:
声明的响应式变量或writable
创建的可写存储),那么当这个对象的属性变化时,Svelte 能够检测到变化并更新依赖的组件。 - 优化性能避免不必要渲染:Svelte 会智能地优化更新,仅在真正影响 DOM 的数据发生变化时才重新渲染组件。对于上下文传递的数据,我们可以通过使用细粒度的响应式声明以及
$: derived
来控制更新的粒度,避免不必要的重新渲染。
实现代码
- 父组件(设置上下文):
<script>
import { setContext } from'svelte';
import { writable } from'svelte/store';
const sharedData = writable({
value: 'initial value'
});
setContext('sharedDataContext', sharedData);
</script>
{#if false}
<!-- 这里添加一些不影响上下文数据的操作,以展示 Svelte 的优化 -->
<div>{Math.random()}</div>
{/if}
{#if true}
<button on:click={() => {
sharedData.update(data => {
data.value = 'new value';
return data;
});
}}>
更新上下文数据
</button>
{/if}
<ChildComponent />
- 子组件(接收上下文):
<script>
import { getContext } from'svelte';
const sharedData = getContext('sharedDataContext');
</script>
<div>
上下文数据: {$sharedData.value}
</div>
在上述代码中:
- 父组件通过
setContext
将一个writable
存储对象sharedData
作为上下文传递。 - 父组件中的按钮点击会更新
sharedData
中的value
属性。 - 子组件通过
getContext
获取这个上下文对象,并在模板中直接使用其value
属性。由于sharedData
是writable
存储,Svelte 能够检测到value
属性的变化并自动更新子组件的视图。 - 在父组件中添加了
{#if false}
块来展示不影响上下文数据的操作不会触发子组件的重新渲染,体现了 Svelte 的性能优化。