javascript 在Svelte中,在嵌套的组件之间调度/转发事件的正确方法是什么?

pw9qyyiw  于 2023-01-29  发布在  Java
关注(0)|答案(2)|浏览(111)

我很好奇,什么是最好的方式来转发或调度事件跨越多层组件树在苗条的JS?
假设我有App.Svelte、一些中间数字级别(每个级别包含一个子组件)和Modal. Svelte,如果我想将事件从Modal转发或分派到App,正确的方法是什么?
据我所知,Svelte中的事件转发将沿着组件树向上遍历,并将事件转发到引用所转发事件的第一个父节点(这是正确的解释吗?)
使用事件调度方法时,每个嵌套组件需要1/导入createEventDispatcher,2/创建一个调度变量,3/定义一个调度事件的函数。然后父组件需要导入该函数并在一个标记内引用它,例如<p>。(这对吗?)
如果以上两点我都是正确的,我想知道是否有一个更精简的方法,例如将事件连接到存储,这将有效地扁平化组件树,使任何组件都可以接收转发的事件。虽然我想象,如果多个组件引用同一个转发的事件,这可能会导致一些难以调试的行为。

yjghlzjz

yjghlzjz1#

要将事件从子组件或DOM元素转发到父组件或DOM元素,您只需定义一个没有处理程序的on:event

<button on:click >
<Component on:open >

不需要仅使用createEventDispatcher进行转发。
如果你想更广泛地共享事件,你可以创建一个EventTarget并通过它发送事件。因为订阅不会在模板中通过on:event发生,你必须确保再次删除侦听器。你也可以使用上下文来只向组件层次结构的子树公开对象。
或者,事件可以直接分派到DOM元素,这样的事件将在整个元素层次结构中冒泡(如果在事件选项中启用)。

someElement.dispatchEvent(
  new CustomEvent('my-event', { bubbles: true })
);

如果您直接或通过冒泡将事件分派到window,则可以使用svelte:window更方便地订阅这些事件:

<svelte:window on:my-event={() => ...} />

(当组件被销毁时,这些处理程序会自动删除。)

pcrecxhr

pcrecxhr2#

你可以考虑使用访问器函数。在App.svelte中,定义一个操作顶级变量的函数,然后将该函数放入一个访问器对象中,并将其作为一个属性传递给所有可能需要它的组件。

<script>
[App.svelte]

let myVar, myObj, myWhatever

function updateMyVal(newValue) {
  myVar = newValue
}

function mergeMyObject(mergeObj) {
  myObj = {...myObj, ...mergeObj}
}

let accessorObject = {
  updateMyVal: updateMyVal,
  mergeMyObject: mergeMyObject
}

</script>

<ChildComponent {accessorObject} {myVar} {myObj} />


. . .
[ChildComponent.svelte]
<script>
  export let accessorObject, myVar, myObj

  accessorObject.updateMyVal(1234)

  accessorObject.mergeMyObject({newProp: newVal})
</script>

等等......这具有自上而下将更改推送到应用程序范围的变量的优点,我发现这比事件、双向绑定或存储的Web更适合复杂的SPA,至少在我有限的经验中是这样。

相关问题