MST

星途 面试题库

面试题:Svelte在实际项目中如何处理组件间通信

请描述在一个实际的Svelte项目场景里,父子组件、非父子组件之间是如何进行数据传递和事件通信的,并举例说明使用到的相关机制与代码实现。
49.5万 热度难度
前端开发Svelte

知识考点

AI 面试

面试题答案

一键面试

父子组件数据传递与事件通信

  1. 父传子数据
    • 机制:通过组件标签属性传递数据。父组件将数据作为属性传递给子组件,子组件通过export let来接收。
    • 代码示例
      • 父组件(App.svelte)
<script>
    let message = 'Hello from parent';
</script>

<ChildComponent {message}/>

<script>
    import ChildComponent from './ChildComponent.svelte';
</script>
 - **子组件(ChildComponent.svelte)**:
<script>
    export let message;
</script>

<p>{message}</p>
  1. 子传父事件
    • 机制:子组件通过createEventDispatcher创建事件分发器,然后使用该分发器触发事件,父组件在子组件标签上监听该事件。
    • 代码示例
      • 子组件(ChildComponent.svelte)
<script>
    import { createEventDispatcher } from'svelte';
    const dispatch = createEventDispatcher();
    function sendDataToParent() {
        dispatch('custom - event', { data: 'Data from child' });
    }
</script>

<button on:click={sendDataToParent}>Send data to parent</button>
 - **父组件(App.svelte)**:
<script>
    function handleChildEvent(event) {
        console.log(event.detail.data);
    }
</script>

<ChildComponent on:custom - event={handleChildEvent}/>

<script>
    import ChildComponent from './ChildComponent.svelte';
</script>

非父子组件数据传递与事件通信

  1. 通过上下文(Context API)
    • 机制:使用setContext在祖先组件中设置上下文数据,后代组件(不论层级多深)使用getContext获取该上下文数据。这可以实现非父子组件间的数据共享。
    • 代码示例
      • 祖先组件(App.svelte)
<script>
    import { setContext } from'svelte';
    let sharedData = 'Shared data for non - parent - child components';
    setContext('shared - data - key', sharedData);
</script>

<DescendantComponent />

<script>
    import DescendantComponent from './DescendantComponent.svelte';
</script>
 - **后代组件(DescendantComponent.svelte)**:
<script>
    import { getContext } from'svelte';
    let sharedData = getContext('shared - data - key');
</script>

<p>{sharedData}</p>
  1. 通过事件总线(自定义事件机制)
    • 机制:创建一个事件总线(一个简单的对象),非父子组件都可以在这个对象上注册事件监听和触发事件,从而实现通信。
    • 代码示例
      • 事件总线文件(eventBus.js)
const eventBus = {
    events: {},
    on(eventName, callback) {
        if (!this.events[eventName]) {
            this.events[eventName] = [];
        }
        this.events[eventName].push(callback);
    },
    emit(eventName, data) {
        if (this.events[eventName]) {
            this.events[eventName].forEach(callback => callback(data));
        }
    }
};

export default eventBus;
 - **组件A(ComponentA.svelte)**:
<script>
    import eventBus from './eventBus.js';
    function sendData() {
        eventBus.emit('non - parent - child - event', { data: 'Data from ComponentA' });
    }
</script>

<button on:click={sendData}>Send data to non - parent - child</button>
 - **组件B(ComponentB.svelte)**:
<script>
    import eventBus from './eventBus.js';
    eventBus.on('non - parent - child - event', (data) => {
        console.log(data);
    });
</script>