如何优雅的处理Form表单数据?

吐槽君 分类:javascript

大家好 我是耗子

这是一个简单的登陆表单:

  <form 
      action="http://localhost:3000/user/login" 
      method="post" 
      id="login-form" 
      enctype="application/x-www-form-urlencoded"
  >
    <label for="username">用户名:</label>
    <input type="text" placeholder="Please Input your username" name="username" id="username">
        <br>
    <label for="password">密码:</label>
    <input type="password" placeholder="Please Input your password" name="password" id="password">
        <br>
    <button type="submit">提交</button>
  </form>
 

如果没有 javascript 进行处理, 当我们点击提交按钮的时候, 表单就会以表单元素 namevalue 作为键值对, 以元素 formmethod 方法发送到 action

image.png

但是一般开发框架中, 我们都会使用 javascript 封装 form , 本文我想和大家分享处理表单的技巧。

使用 Javascript 获取表单数据

1. 获取表单

  • 通过 document.getElementBy** , querySelector 等方法 (过于常用就不多赘述了)

  • 通过 document.forms[id/index] 获取指定表单
    image.png

2. 阻止表单默认事件

这是为了阻止表单默认的 跳转 和 发送数据, 我们通过监听 form 元素的 submit 事件进行,

这里有两种方式:

  • return false
  • 通过 event 对象, 设置 e.preventDefault

ps: return false 等价于 e.preventDefault() + e.stopPropagation()

let form = document.getElementById("login-form");
form.onsubmit = (event) => {
  return false;
}
 

现在我们点击 submit 按钮将不再自动发送数据并跳转了。

3. 处理表单数据

那么现在我们开始处理表单数据:

  • 通过 name 属性和 id 都可以获取对应表单控件:

    image.png

  • 通过 form 加 索引获取:

image.png

  • 通过 FormData 批量获取数据:

    image.png

    需要注意的是, formData 是数据快照, 相当于通过 namevalue 生成对象。

    当数据再度变化, formData 必须重新创建。

    其次 formData 不能直接获取内容, 必须通过 entries() 相关的循环 或 get 获取。

    ps: 我们可以通过在 HTMLFormElement 原型上添加 formData 属性来简化操作:

    image.png

    通过同样的方法, 我们还可以进行数据的封装。

  • 封装JSON表单:

    Object.defineProperty(HTMLFormElement.prototype, 'jsonData', {
       get() {
           const jsonData = {};
           const formData = new FormData(this);
           formData.append("1", "2");
           formData.append("1", "3");
           formData.forEach((value, key) => {
               if (!jsonData[key]) {
                   jsonData[key] = formData.getAll(key);
                   if (jsonData[key].length < 1) jsonData[key] = "";
                   else if (jsonData[key].length === 1) jsonData[key] = jsonData[key][0];
               }
           });
           return jsonData;
       }
    })
     

    image.png

4. 发送表单数据

  • form.submit() 正常发送数据并跳转

  • 在 onsubmit 中使用 Ajax 发送 3. 中封装的表单对象

    let xhr = new XMLHttpRequest();
    xhr.open("POST", '/server', true);
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    xhr.send(FormData data);
     

React 中的表单数据处理

受控组件 (推荐)

指的是 双向绑定表单控件, 将表单控件value值与组件state关联:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('提交的名字: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          名字:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="提交" />
      </form>
    );
  }
}
 

更多受控组件

非受控组件

表单组件交由原生DOM组件维护, 通过创建 ref 从原生表单控件中获取值:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.input = React.createRef();
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.input.current.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={this.input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
 

结语

感谢您的观看, 点赞和关注是对我最大的支持。

也欢迎大家对文中的内容进行补充和讨论!

XboxYan 大佬的 如何优雅的获取form表单数据

回复

我来回复
  • 暂无回复内容