创建受控元素
在 React 中,表单元素默认是受控的,需要使用组件传递数据给表单元素以修改表单元素的值,这有许多的好处:
- 单一数据来源
- 渲染前处理用户输入
Gem 默认没有处理此行为,你可以像 Vanilla JS 一样处理表单:
你可以利用 input 事件 自行创建受控表单元素:
监听
input事件,储存新值@customElement('form-text') export class FormTextElement extends GemElement { #inputRef = createRef<HTMLInputElement>(); #nextState = ''; #inputHandle = (e: InputEvent) => { this.#nextState = this.#inputRef.value!.value; }; render = () => { return html`<input ${this.#inputRef} @input=${this.#inputHandle} />`; } } 还原旧值并触发自定义
change事件@customElement('form-text') export class FormTextElement extends GemElement { #inputRef = createRef<HTMLInputElement>(); @attribute value: string; @emitter change: Emitter<string>; #nextState = ''; #inputHandle = (e: InputEvent) => { this.#nextState = this.#inputRef.value!.value; this.#inputRef.value!.value = this.value; this.change(value); }; render = () => { return html`<input ${this.#inputRef} @input=${this.#inputHandle} />`; } } 根据属性修改
<input>元素值@customElement('form-text') export class FormTextElement extends GemElement { #inputRef = createRef<HTMLInputElement>(); @attribute value: string; @emitter change: Emitter<string>; #nextState = ''; #inputHandle = (e: InputEvent) => { this.#nextState = this.#inputRef.value!.value; this.#inputRef.value!.value = this.value; this.change(value); }; @effect((i) => [i.value]) #updateValue = () => { if (this.value === this.nextState.value) { this.#inputRef.value!.value = this.nextState.value; } else { this.#inputRef.value!.value = this.value; } }; render = () => { return html`<input ${this.#inputRef} @input=${this.#inputHandle} />`; } }
现在 <form-text> 就是一个受控元素,它只接收 value 属性的值:
最后,你可能需要利用 selectionStart/selectionEnd 处理指针位置、isComposing 处理输入法候选。
上次更新:
2025/06/09 15:30:31