MST

星途 面试题库

面试题:Svelte复杂场景下生命周期与异步数据加载

假设你正在开发一个Svelte应用,有多个组件存在嵌套关系,每个组件都可能需要异步加载数据,并且当父组件数据更新时,子组件需要重新加载相关异步数据。描述你会如何设计组件结构和使用生命周期函数来实现该功能,同时说明如何避免不必要的重复加载。
30.7万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试
  1. 组件结构设计
    • 父组件
      • 作为数据的主要管理者,维护共享状态。例如,假设父组件管理一个列表数据的筛选条件。
      <script>
        let filter = '';
        function updateFilter(newFilter) {
          filter = newFilter;
        }
      </script>
      <ChildComponent {filter} on:updateFilter={updateFilter}/>
      
    • 子组件
      • 接受父组件传递的依赖数据作为props,如上述的filter。子组件根据这个props来异步加载数据。
      <script>
        export let filter;
        let data = [];
        async function loadData() {
          // 这里根据filter进行异步数据加载
          const response = await fetch(`/api/data?filter=${filter}`);
          data = await response.json();
        }
      </script>
      {#if data.length > 0}
        {#each data as item}
          <p>{item}</p>
        {/each}
      {:else}
        <p>Loading...</p>
      {/if}
      
  2. 生命周期函数使用
    • 父组件
      • 当父组件数据更新时,触发子组件重新加载数据。这里可以利用Svelte的set语句来更新数据,Svelte会自动响应式地更新相关DOM和依赖组件。例如,在updateFilter函数中更新filter后,子组件会感知到filter的变化。
    • 子组件
      • 使用onMount生命周期函数在组件首次挂载时加载数据。
      <script>
        import { onMount } from'svelte';
        export let filter;
        let data = [];
        async function loadData() {
          const response = await fetch(`/api/data?filter=${filter}`);
          data = await response.json();
        }
        onMount(() => {
          loadData();
        });
      </script>
      
      • 为了在filter变化时重新加载数据,可以使用$:响应式语句。
      <script>
        import { onMount } from'svelte';
        export let filter;
        let data = [];
        async function loadData() {
          const response = await fetch(`/api/data?filter=${filter}`);
          data = await response.json();
        }
        onMount(() => {
          loadData();
        });
        $: {
          loadData();
        }
      </script>
      
  3. 避免不必要的重复加载
    • 使用记忆化
      • 可以使用lodashmemoize函数(或者自行实现简单的记忆化逻辑)来避免重复请求相同数据。例如,创建一个记忆化的loadData函数。
      <script>
        import { onMount } from'svelte';
        import memoize from 'lodash/memoize';
        export let filter;
        let data = [];
        const memoizedLoadData = memoize(async () => {
          const response = await fetch(`/api/data?filter=${filter}`);
          return await response.json();
        });
        onMount(async () => {
          data = await memoizedLoadData();
        });
        $: {
          data = await memoizedLoadData();
        }
      </script>
      
    • 比较数据变化
      • 在子组件中,可以在filter变化时,先比较新的filter和旧的filter,如果没有变化则不重新加载数据。
      <script>
        import { onMount } from'svelte';
        export let filter;
        let oldFilter = '';
        let data = [];
        async function loadData() {
          const response = await fetch(`/api/data?filter=${filter}`);
          data = await response.json();
        }
        onMount(() => {
          oldFilter = filter;
          loadData();
        });
        $: {
          if (filter!== oldFilter) {
            oldFilter = filter;
            loadData();
          }
        }
      </script>