简体   繁体   English

Stencil.js - 事件监听器的解释

[英]Stencil.js - explanation of event listeners

Consider the following simple input component:考虑以下简单的input组件:

import { Component, VNode, h, Prop, Host } from '@stencil/core'

@Component({
  tag: 'my-input',
})
export class MyInput {
  @Prop() inputId!: string
  @Prop() label!: string
  @Prop() value: string

  render(): VNode {
    return (
      <Host>
        <label htmlFor={this.inputId}>{this.label}</label>
        <input type="text" id={this.inputId} value={this.value}  />
      </Host>
    )
  }
}

Parent component that renders <my-input> component with couple of event listeners:使用几个事件侦听器呈现<my-input>组件的父组件:

import { Component, h, VNode } from '@stencil/core'

@Component({
  tag: 'my-page',
})
export class MyPage {
  private handleInput = (ev: Event) => {
    // this works
    console.log('handle input')
  }

  private handleFocus = (ev: Event) => {
    // this doesn't work
    console.log('handle focus')
  }

  private handleClick = (ev: Event) => {
    // this works
    console.log('handle click')
  }

  private handleBlur = (ev: Event) => {
    // this doesn't work
    console.log('handle blur')
  }

  render(): VNode {
    return (
      <my-input
        label="Label"
        inputId="testId"
        onInput={this.handleInput}
        onFocus={this.handleFocus}
        onClick={this.handleClick}
        onBlur={this.handleBlur}
      />
    )
  }
}

Would someone explain to me please, how it's possible that some of the listeners actually work and the rest do not?请有人向我解释一下,一些听众怎么可能实际工作而 rest 不能?

The reason the focus and blur event handlers don't fire is because you're attaching the listeners to the my-input element and not the actual input element.焦点和模糊事件处理程序不触发的原因是因为您将侦听器附加到my-input元素而不是实际的input元素。 That means only the listeners of events that bubble will fire (click, input) and the rest (focus, blur) won't.这意味着只有气泡会触发事件的侦听器(单击、输入)而 rest(焦点、模糊)不会。

One way to enable the use of those non-bubbling events is to proxy them:启用这些非冒泡事件的一种方法是代理它们:

export class MyInput {
  @Event() myFocus: EventEmitter<FocusEvent>;

  render() {
    return (
      <Host>
        <label htmlFor={this.inputId}>{this.label}</label>
        <input type="text" id={this.inputId} value={this.value} onFocus={e => this.myFocus.emit(e)} />
      </Host>
    )
  }
}

Here I've attached an focus event handler to the input and fire the custom myFocus event which you can listen for from outside the component.在这里,我将focus事件处理程序附加到input并触发自定义myFocus事件,您可以从组件外部侦听该事件。 You might also want to stop these events from bubbling by changing the decorator to @Listen({ bubbles: false }) myFocus;您可能还想通过将装饰器更改为@Listen({ bubbles: false }) myFocus;

This is also how the Ionic Framework (made by the same people as Stencil) does it, see https://github.com/ionic-team/ionic-framework/blob/master/core/src/components/input/input.tsx#L220这也是 Ionic 框架(由与 Stencil 相同的人制作)的方式,请参阅https://github.com/ionic-team/ionic-framework/blob/master/core/src/components/input/input。 tsx#L220

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM