杭州电子商务研究院

在本地存储自动完成/预输入字段的数据

2020-08-31 08:00飞浪

介绍

自动填充字段是必备的用户界面组件,可增强应用的整体用户体验。当用户搜索特定术语时,它们还有助于最大限度地减少冗余拼写错误。由于访问客户端存储的速度非常快,您的应用的性能也会得到提高。

在本指南中,您将学习如何从头开始创建自动完成字段并在浏览器中本地存储搜索建议。

客户端存储

客户端存储是 HTML5 在浏览器上最有用和最具未来感的功能之一。它有助于将处理负载从服务器会话转移到客户端变量。

客户端存储的类型包括:

  • 会话存储
  • 本地存储
  • Web SQL
  • 索引数据库
  • 文件系统

本指南将使用本地存储,因为与其他类型的存储相比,它具有简单的 API。

使用localStorage API,您可以访问特定域或网站的本地存储。数据以键值对格式存储在本地存储中。

以下代码片段访问本地存储并使用localStorage.setItem()方法向其中添加数据项。

      localStorage.setItem("Name", "John Doe");
    

第一个参数是键的名称,第二个参数是其对应的值。

要从本地存储中检索项目,请使用localStorage.getItem()方法并将键作为参数传递。

      localStorage.getItem("Name");
    

开始使用组件

现在您可以开始处理AutoComplete组件。如下所示,您需要在状态对象中拥有三个属性。inputValue属性将保存文本输入的值,filteredOptions属性将保存实际的过滤结果,options属性将包含之前在数组中输入的所有可用选项。

      class AutoComplete extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: "",
      filteredOptions: [],
      options: localStorage.getItem("autocompleteOptions")
        ? JSON.parse(localStorage.getItem("autocompleteOptions"))
        : [],
    };

    // ...
  }

  render() {
    // ...
  }
}
    

在render()方法内部,显示输入字段并添加显示结果的逻辑。

      class AutoComplete extends Component {
  constructor(props) {
    // ...
  }

  render() {
    return (
      <div className="autocomplete-container">
        <input
          type="text"
          value={this.state.inputValue}
          onChange={this.handleInputChange}
          onKeyDown={this.handleKeyDown}
        />
        <ul className="autocomplete-results">
          {this.state.inputValue.length > 0 &&
            this.state.filteredOptions.map((option) => (
              <li key={option}>{option}</li>
            ))}
        </ul>
      </div>
    );
  }
}
    

在handleInputChange()方法中,设置状态中的inputValue ,并使用Array.prototype.filter()方法过滤选项。要确定输入中输入的术语是否存在于可用选项中,可以使用indexOf方法。

indexOf ()方法返回调用String对象中指定子字符串或值第一次出现的索引或位置值。如果在字符串中未找到该值,则返回-1 。

在handleKeyDown()方法中,当用户按下键盘上的 Enter 键时,将输入的值添加到可用选项列表中。Enter键的keyCode为 13,因此您可以使用本机事件对象在函数主体内检查输入值的keyCode是否等于 13 。

      class AutoComplete extends Component {
  constructor(props) {
    // ...
  }

  handleInputChange(e) {
    const userInput = e.target.value;
    this.setState({ inputValue: userInput });
    const filteredOptions = this.state.options.filter(
      (option) => option.toLowerCase().indexOf(userInput.toLowerCase()) > -1
    );
    this.setState({ filteredOptions });
  }

  handleKeyDown(e) {
    if (e.keyCode === 13) {
      const userInput = e.target.value;
      this.addOption(userInput);
      this.setState({ inputValue: "" });
    }
  }

  render() {
    // ...
  }
}
    

将数据存储在本地存储中

在addOption()方法中,在选项状态中设置输入的值,并立即将更新后的选项状态存储在本地存储中。不要忘记将数组转换为字符串,因为本地存储不支持存储对象。

      class AutoComplete extends Component {
  constructor(props) {
    // ...
  }

  addOption(option) {
    this.setState({ options: [...this.state.options, option] }, () => {
      localStorage.setItem(
        "autocompleteOptions",
        JSON.stringify(this.state.options)
      );
    });
  }

  // ...

  render() {
      // ...
  }
    

美化组件

好了,现在组件已经准备好了,添加一些样式让它看起来更漂亮,因为没有人喜欢看到默认的浏览器样式。您可以复制下面的 CSS 代码,也可以自己添加样式。

      .App {
  font-family: sans-serif;
  text-align: center;
}

.autocomplete-container {
  width: 450px;
  margin: auto;
}

.autocomplete-container input {
  padding: 10px 18px;
  font-size: 20px;
  width: 100%;
  border: 2px solid #999;
  border-radius: 6px;
}

ul.autocomplete-results {
  margin: 0;
  margin-top: 8px;
  list-style-type: none;
  padding: 0;
}

ul.autocomplete-results li {
  text-align: left;
  padding: 10px 18px;
  margin-bottom: 4px;
  width: 100%;
  box-shadow: 0px 3px 10px rgba(0, 0, 0, 0.08);
  border: 1px solid #eee;
  background: #fefefe;
}
    

完整代码

下面您可以找到AutoComplete组件的完整代码供您参考。

      import React, { Component } from "react";

class AutoComplete extends Component {
  constructor(props) {
    super(props);
    this.state = {
      inputValue: "",
      filteredOptions: [],
      options: localStorage.getItem("autocompleteOptions")
        ? JSON.parse(localStorage.getItem("autocompleteOptions"))
        : [],
    };

    this.addOption = this.addOption.bind(this);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.handleKeyDown = this.handleKeyDown.bind(this);
  }

  addOption(option) {
    this.setState({ options: [...this.state.options, option] }, () => {
      localStorage.setItem(
        "autocompleteOptions",
        JSON.stringify(this.state.options)
      );
    });
  }

  handleInputChange(e) {
    const userInput = e.target.value;
    this.setState({ inputValue: userInput });
    const filteredOptions = this.state.options.filter(
      (option) => option.toLowerCase().indexOf(userInput.toLowerCase()) > -1
    );
    this.setState({ filteredOptions });
  }

  handleKeyDown(e) {
    if (e.keyCode === 13) {
      const userInput = e.target.value;
      this.addOption(userInput);
      this.setState({ inputValue: "" });
    }
  }

  render() {
    return (
      <div className="autocomplete-container">
        <input
          type="text"
          value={this.state.inputValue}
          onChange={this.handleInputChange}
          onKeyDown={this.handleKeyDown}
        />
        <ul className="autocomplete-results">
          {this.state.inputValue.length > 0 &&
            this.state.filteredOptions.map((option) => (
              <li
                key={option}
                onClick={() =>
                  this.setState({ inputValue: option, filteredOptions: [] })
                }
              >
                {option}
              </li>
            ))}
        </ul>
      </div>
    );
  }
}

export default AutoComplete;
    

结论

这就是本指南的全部内容。您已成功创建完美的AutoComplete组件。您可以使用 ajax 调用将服务器端结果与客户端结果相结合,进一步利用此组件。使用客户端存储进行适当的状态管理和实施可以使您的应用速度惊人地快,并为您的用户提供更好的用户体验。

曝光33506浏览1766