MST

星途 面试题库

面试题:Svelte模板语法的组件通信优化

假设你正在开发一个具有多层嵌套组件的Svelte应用,描述如何通过Svelte的模板语法有效地进行父子组件以及跨层级组件之间的通信,并说明在这个过程中如何避免数据传递的冗余和性能问题。
43.6万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试

父子组件通信

  1. 父传子
    • 在父组件模板中,通过属性绑定将数据传递给子组件。例如:
    <!-- 父组件 -->
    <script>
      let parentData = "Hello from parent";
    </script>
    <ChildComponent {parentData} />
    
    • 在子组件中,通过声明对应的属性来接收数据。例如:
    <!-- 子组件 -->
    <script>
      export let parentData;
    </script>
    <p>{parentData}</p>
    
  2. 子传父
    • 在子组件中,通过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} />
    

跨层级组件通信

  1. Context API
    • 使用setContextgetContext。例如,在祖先组件中设置上下文数据:
    <!-- 祖先组件 -->
    <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>
    
  2. 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>
    

避免数据传递冗余和性能问题

  1. 数据流动优化
    • 尽量保持单向数据流,明确数据的来源和流向,减少不必要的数据传递。例如,对于父子组件通信,确保子组件只接收它实际需要的数据,避免传递过多无关数据。
  2. 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>
    
  3. 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}
    
    • 这样可以避免在应用启动时加载所有组件,从而提高性能。