首页 > 解决方案 > 如何在Vue中正确使用基于数据库源的自动完成输入字段?

问题描述

我想根据来自数据源的记录使用建议自动完成的输入字段(或类似的东西)。

在 Vue 中,我从包含 3000 多条记录的数据库表中检索一个数组:

data(){
    return{
      inboundRelation_Trelation_data: [],
    }
  },

mounted(){

     axios.get('/app/wms/allRelations', {
                  params: {
                    "dbConn": this.connString,
                  }
                })
     .then(response => this.inboundRelation_Trelation_data = response.data);
  },

根据这些数据,我想要一个自动完成输入字段和/或下拉菜单。我在网上找到了两种方法.. 1:

<select v-model="form.CUSTOMER_NAME">
                <option v-for="(relation, index) in inboundRelation_Trelation_data" :value="relation.RELATIONCODE" v-text="relation.COMPANYNAME + ' | ' + relation.RELATIONCODE"></option>
</select>

这会填充一个下拉列表,但我的用户觉得这很乏味,因为他们需要快速输入字母,否则在短暂的停顿(如 <0.5 秒)后,下一个输入的字母将开始新的搜索,结果不一致。

另一种方法是使用数据列表:

<input list="allRelations" type="text" @focus="$event.target.select()" v-model="form.CUSTOMER_NAME">
              <datalist id="allRelations">
                <option v-for="(relation, index) in inboundRelation_Trelation_data" :value="relation.RELATIONCODE" v-text="relation.COMPANYNAME + ' | ' + relation.RELATIONCODE"></option>
</datalist>

这对于少量数据非常有效。但是在处理 100 多条记录(或在本例中为 3000 多条)时,整个浏览器会在输入字母时冻结。出于某种原因,这是一个非常耗费资源的实现。我发现一些人有类似的问题,但没有解决方案。

归根结底,我只希望我的用户能够在包含 3000 多条记录的庞大列表中进行搜索。我该如何处理?

标签: htmllaravelvue.jsaxios

解决方案


您可以通过此 github 链接使用 vue-autosuggest 包:
https ://github.com/darrenjennings/vue-autosuggest

我正在使用这个包,我的数据按我的预期加载。

这是您可以使用的模板:

<template>
<div class="autosuggest-container">
  <vue-autosuggest
    v-model="form.CUSTOMER_NAME"
    :suggestions="filteredOptions"
    @focus="focusMe"
    @click="clickHandler"
    @input="onInputChange"
    @selected="onSelected"
    :get-suggestion-value="getSuggestionValue"
    :input-props="{
      class: 'form-control',
      id: 'autosuggest__input',
      field: 'CUSTOMER_NAME',
      placeholder: 'Enter customer name for auto suggest',
    }"
  >
    <div
      slot-scope="{ suggestion }"
      style="display: flex; align-items: center"
    >
      <img
        :style="{
          display: 'flex',
          width: '25px',
          height: '25px',
          borderRadius: '15px',
          marginLeft: '10px',
        }"
        :src="suggestion.item.avatar"
      />
      <div style="{ display: 'flex', color: 'navyblue'}">
        {{ suggestion.item.CUSTOMER_NAME }}
      </div>
    </div>
  </vue-autosuggest>
</div>

和脚本部分:

<script>
export default {
  data() {
    return {
      searching: false,
      query: '',
      selected: '',
      suggestions: [],
    }
  },
  computed: {
    filteredOptions() {
      return [
        {
          data: this.suggestions.filter((option) => {
            return (
              option.name.toLowerCase().indexOf(this.query.toLowerCase()) > -1
            )
          }),
        },
      ]
    },
  },
  methods: {
    clickHandler() {
      //
    },
    onSelected(item) {
      this.selected = item.item
    },
    async onInputChange(text = '') {
      this.searching = true
      await this.$axios
        .get(`/app/wms/allRelations`,{
                  params: {
                    "dbConn": this.connString,
                  })
        .then((res) => {
          this.suggestions = res.data.data
        })
        .catch((e) => console.log(e))
        .finally(() => (this.searching = false))
    },
    getSuggestionValue(suggestion) {
      return suggestion.item.name
    },
    focusMe(e) {
      this.onInputChange()
    },
  },
}
</script>

如果您的浏览器仍然冻结,您必须将您的 API 响应限制更改为下降 10 项。


推荐阅读