面试题答案
一键面试分析
- 不必要的更新触发:子组件可能因为父组件状态变化,即使自身数据未改变也触发更新,导致生命周期函数不必要调用。
- 复杂计算在生命周期中:生命周期函数内执行复杂计算,增加渲染时间。
- 重复订阅和清理:多次在子组件中订阅相同事件,在销毁时重复清理,增加开销。
优化策略
- 减少不必要更新
- 使用
{#if condition}
有条件渲染组件,避免不需要渲染的组件触发生命周期。 - 利用
bind:this
来控制组件更新,只有在需要时才更新。
- 使用
- 优化生命周期内计算
- 将复杂计算提前到组件初始化时完成,避免在
onMount
等生命周期函数内重复计算。 - 使用
$:
响应式语句优化局部变量计算,避免每次更新都重新计算。
- 将复杂计算提前到组件初始化时完成,避免在
- 合并订阅和清理
- 在父组件进行统一的事件订阅和清理,通过传递函数给子组件来处理事件,避免子组件重复操作。
代码示例
- 减少不必要更新
<!-- 父组件 -->
<script>
let showChild = true;
let count = 0;
const increment = () => {
count++;
};
</script>
<button on:click={increment}>Increment</button>
{#if showChild}
<Child {count}/>
{/if}
<!-- 子组件 -->
<script>
export let count;
let localValue = 0;
$: localValue = count * 2;
console.log('Child component updated');
</script>
<p>Local value: {localValue}</p>
在此例中,通过 {#if}
控制子组件是否渲染,避免了子组件不必要更新。
- 优化生命周期内计算
<!-- 父组件 -->
<script>
let data = [];
onMount(() => {
// 提前计算复杂数据
data = Array.from({ length: 1000 }, (_, i) => i + 1);
});
</script>
<Child {data}/>
<!-- 子组件 -->
<script>
export let data;
let sum = 0;
$: sum = data.reduce((acc, val) => acc + val, 0);
</script>
<p>Sum of data: {sum}</p>
父组件在 onMount
提前计算数据,子组件通过 $:
优化计算。
- 合并订阅和清理
<!-- 父组件 -->
<script>
let message = '';
const handleMessage = (newMessage) => {
message = newMessage;
};
onMount(() => {
window.addEventListener('message', handleMessage);
return () => {
window.removeEventListener('message', handleMessage);
};
});
</script>
<Child {message}/>
<!-- 子组件 -->
<script>
export let message;
</script>
<p>Received message: {message}</p>
父组件统一进行事件订阅和清理,子组件只接收数据。