痛点:为什么 input.value = 'xxx' 无效?

在传统的 jQuery 时代,我们要修改一个输入框的值,只需要:

$('#username').val('admin');

但在 React、Vue 等现代框架中,这种做法往往无效。页面上虽然显示了值,但当你点击提交按钮时,表单却提示"用户名不能为空"。

原因解析:
React 使用**受控组件(Controlled Components)**模式。Input 的值由 State 驱动(State -> View)。直接修改 DOM 的 value 属性(View 层),并不会更新 React 的 State。当 React 下次重渲染时,它会发现 State 还是空的,于是又把 Input 的值清空了。

AutoForm 的解决方案

AutoForm 深入研究了 React 和 Vue 的源码,总结出了一套能够完美触发框架状态更新的方案。

核心原理:模拟真实用户输入

既然直接改值不行,那我们就模拟用户的真实操作。用户输入时会触发一系列事件:focus -> keydown -> input -> change -> blur。

我们需要完整触发这些事件。

关键黑科技:原生 Value Setter 劫持

对于 React 16+,它重写了 input 的 value setter。为了绕过 React 的拦截,我们需要调用原生的 setter。

function setNativeValue(element: HTMLInputElement, value: string) {
  // 获取原生的 value 属性描述符
  const valueSetter = Object.getOwnPropertyDescriptor(element, 'value').set;
  const prototype = Object.getPrototypeOf(element);
  const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set;

  // 核心:调用原型链上的 setter,绕过 React 的封装
  if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
    prototypeValueSetter.call(element, value);
  } else {
    valueSetter.call(element, value);
  }

  // 触发 input 事件,通知 React 值变了
  element.dispatchEvent(new Event('input', { bubbles: true }));
}

完整流程代码

AutoForm 封装了一个 fillInput 函数,确保万无一失:

async function fillInput(element: HTMLInputElement, value: string) {
  // 1. 聚焦
  element.focus();
  element.dispatchEvent(new Event('focus', { bubbles: true }));

  // 2. 设置值(使用黑科技)
  setNativeValue(element, value);

  // 3. 触发 input 事件
  // React 监听的是 input 事件来更新 state
  
  // 4. 触发 change 事件
  // 某些老旧框架或原生代码监听 change
  element.dispatchEvent(new Event('change', { bubbles: true }));

  // 5. 失焦
  element.blur();
  element.dispatchEvent(new Event('blur', { bubbles: true }));
}

针对 Vue 的特殊处理

Vue 的 v-model 本质上是监听 input 事件(对于 text 类型)。上述的 setNativeValue + dispatchEvent('input') 方案对 Vue 同样有效。

但在 Vue 2 中,某些组件(如 Select)可能监听的是 change 事件,所以同时触发 input 和 change 是最保险的。

总结

自动化填充不仅仅是 value = xxx 那么简单。要兼容现代前端框架,必须深入理解它们的事件机制和状态管理原理。

AutoForm 通过模拟真实事件链和绕过框架拦截,实现了对 React、Vue、Angular 等所有主流框架的完美支持。


本文作者:AutoForm 核心开发
关键词:React, 受控组件, 自动化测试, 模拟输入, 前端黑科技

👉 **官网地址:https://51bpms.com**

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐