Consider the following simple input
component:
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:
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?
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. That means only the listeners of events that bubble will fire (click, input) and the rest (focus, blur) won't.
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. You might also want to stop these events from bubbling by changing the decorator to @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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.