简体   繁体   English

在 Svelte 中跨嵌套组件分派/转发事件的正确方法是什么?

[英]What's the correct way to dispatch/forward events across nested in components in Svelte?

I'm curious, what's the best way to forward or dispatch events across multiple levels in component tree in Svelte JS?我很好奇,在 Svelte JS 的组件树中跨多个级别转发或分派事件的最佳方式是什么?

Say I have App.Svelte, some intermediate number levels, each containing a child component, and Modal.Svelte.假设我有 App.Svelte,一些中间数字级别,每个级别都包含一个子组件,以及 Modal.Svelte。 If I want to forward or dispatch an event from Modal to App, what's the right way to do this?如果我想将事件从 Modal 转发或分派到 App,正确的方法是什么?

As I understand it, event forwarding in Svelte will traverse up the component tree and forward the event to the first parent that references the forwarded event.据我了解,Svelte 中的事件转发将向上遍历组件树并将事件转发给引用转发事件的第一个父级。 (Is this the correct interpretation?) (这是正确的解释吗?)

And using event dispatch approach, each nested component would need to 1/ import createEventDispatcher, 2/ create a dispatcher variable, 3/ define a function, which dispatches the event.并且使用事件调度方法,每个嵌套组件需要 1/ 导入 createEventDispatcher,2/ 创建一个调度程序变量,3/ 定义一个 function,它调度事件。 Then parent's would need to import the function and reference it inside a tag, such as <p> .然后父母需要导入 function 并在标签内引用它,例如<p> (Is this correct?) (这样对吗?)

If I'm correct on both of the above, I'm wondering if there isn't a more streamlined approach, eg connecting the event to stores, which would effectively flatten the component tree such that any component could receive the forwarded event.如果我在上述两个方面都是正确的,我想知道是否有更简化的方法,例如将事件连接到存储,这将有效地展平组件树,以便任何组件都可以接收转发的事件。 Though I imagine that this could induce some hard to debug behavior if multiple components reference the same forwarded event.尽管我认为如果多个组件引用相同的转发事件,这可能会导致一些难以调试的行为。

To forward a event from a child component or DOM element to the parent, you just have to define an on:event without handler.要将事件从子组件或 DOM 元素转发到父组件,您只需定义一个不带处理程序的on:event Eg例如

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

No need to use createEventDispatcher just for forwarding.不需要仅仅为了转发而使用createEventDispatcher

If you want to share events more widely, you can create an EventTarget and send events through that.如果您想更广泛地共享事件,您可以创建一个EventTarget并通过它发送事件。 Since subscriptions would not happen in the template via on:event , you have to make sure to remove listeners again.由于模板中不会通过on:event进行订阅,因此您必须确保再次删除监听器。 You can also use a context to just expose the object to a sub-tree of the component hierarchy.您还可以使用上下文将 object 暴露给组件层次结构的子树。

Alternatively, events can be dispatched directly to DOM elements, such events will bubble up the entire element hierarchy (if enabled in the event options).或者,可以将事件直接分派给 DOM 元素,这样的事件将在整个元素层次结构中冒泡(如果在事件选项中启用)。

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

If you dispatch events to the window , directly or via bubbling, you can subscribe to those more conveniently using svelte:window :如果您直接或通过冒泡将事件发送到window ,您可以使用svelte:window更方便地订阅这些事件:

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

(These handlers are removed automatically when the component is destroyed.) (当组件被销毁时,这些处理程序会自动删除。)

You might consider instead using accessor functions.您可能会考虑改用访问器函数。 In App.svelte, define a function that manipulates your top-level variables.在 App.svelte 中,定义一个 function 来操作您的顶级变量。 Then place that function in an accessor object and pass that down as a prop to all your components that may need it.然后将 function 放在访问器 object 中,并将其作为 prop 传递给可能需要它的所有组件。

<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>

And so forth... this has the advantage of pushing changes to application-wide variables from the top down, which I've found to work better for complex SPAs than a web of events, two-way-bindings or stores, at least in my limited experience.等等......这具有自上而下推动对应用程序范围变量的更改的优势,我发现它对于复杂的 SPA 比 web 的事件、双向绑定或存储更有效,至少以我有限的经验。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在 Svelte 完成渲染 dom 后运行代码的正确方法是什么? - What's the correct way to run code after Svelte is done rendering the dom? 在Redux / React组件中更改props值的正确方法是什么? - What's the correct way to mutate props value in Redux/React components? 用SVG文档拦截html中的键盘事件的正确方法是什么? - What's the correct way to intercept keyboard events in html with an SVG document? 将 js 类导入 Svelte 组件的正确方法是什么? - What is the correct way to import a js class into a Svelte component? 处理嵌套在组件中的组件的 JS 事件的最佳方法? - Best way to handle JS events for components nested in components? 访问嵌套的JSON以在Vue.JS组件中使用的正确方法是什么? - What is the correct way to access nested JSON for use in Vue.JS components? 在 React 组件中使用自定义 api 客户端的惯用方式是什么? - What's the Idiomatic way for using custom api client across react components? 在Vue中的不同组件之间共享监视属性的最佳方法是什么? - What's the best way to share a watched property across different components in Vue? 导出命名组件的正确方法是什么? - What is the correct way to export named components? 单独导入 Vuetify 组件的正确方法是什么? - What is the correct way to import Vuetify components individually?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM