【问题标题】:VueJS Autocomplete with array of objects带有对象数组的VueJS自动完成
【发布时间】:2023-03-22 15:15:02
【问题描述】:

我尝试从我在 github 上找到的一个组件修改一个自动完成组件,但我在显示我的值时遇到了问题

这是我的 Autocomplete.vue

 <template>
  <div style="position:relative" v-bind:class="{'open':openSuggestion}">
    <input class="form-control" type="text" :value="value" @input="updateValue($event.target.value)"
           @keydown.enter='enter'
           @keydown.down='down'
           @keydown.up='up'
    >
    <ul class="dropdown-menu" style="width:100%">
      <li v-for="(suggestion, index) in matches"
          v-bind:class="{'active': isActive(index)}"
          @click="suggestionClick(index)"
      >
        <a href="#">{{ suggestion.name }}
          <small>{{ suggestion.id}}</small>
        </a>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    props: {
      value: {
        //type: Object,
        required: true
      },
      suggestions: {
        type: Array,
        required: true
      }
    },
    data () {
      return {
        open: false,
        current: 0
      }
    },
    computed: {
      // Filtering the suggestion based on the input
      matches () {
        return this.suggestions.filter((obj) => {
          return obj.name.indexOf(this.value) >= 0
        })
      },
      openSuggestion () {
        return this.selection !== '' &&
          this.matches.length !== 0 &&
          this.open === true
      }
    },
    methods: {
      updateValue (value) {
        if (this.open === false) {
          this.open = true
          this.current = 0
        }
        this.$emit('input', value)
      },
      // When enter pressed on the input
      enter () {
        this.$emit('input', this.matches[this.current])
        this.open = false
      },
      // When up pressed while suggestions are open
      up () {
        if (this.current > 0) {
          this.current--
        }
      },
      // When up pressed while suggestions are open
      down () {
        if (this.current < this.matches.length - 1) {
          this.current++
        }
      },
      // For highlighting element
      isActive (index) {
        return index === this.current
      },
      // When one of the suggestion is clicked
      suggestionClick (index) {
        this.$emit('input', this.matches[index])
        this.open = false
      }
    }
  }
</script>

我像这样使用我的组件:

 <autocomplete :suggestions="allBranchesEconomiquesActives" v-model="modifiedElementRegistre.personneMorale.brancheEconomique"></autocomplete>

其中 allBranchesEconomiquesActives 是一个对象数组:

[
{code:"A"
id:1
isActif:true
name:"Branche1"},
{code:"B"
id:2
isActif:true
name:"Branche2"},
....
]

modifiedElementRegistre.personneMorale.brancheEconomique我的模型

当我从建议列表中选择一个元素时,我的问题是我的输入显示“[object Object]”。如果我在输入中输入 ":value="value.name" ,我不能在输入中写入,值总是被重置(只保留最后输入的字符)

我怎样才能让我的对象在我的模型中并在我的输入中正确显示?

【问题讨论】:

  • 自动完成是什么意思?似乎选择以搜索结果作为选项。
  • 是的,它只是一个带有建议列表的输入。包含建议的
  • 工作正常,但是当我选择一个项目时,我的输入显示 [Object Object]。有空的时候我会试着提琴

标签: autocomplete vuejs2


【解决方案1】:

你的输入显示[Object Object],因为你给它整个对象,而字符串是预期的。 为了能够编辑&lt;input&gt; 的值,您可以复制value 属性的名称并将v-model 与该副本一起使用。根据需要将复制值重置为初始值/新值。

<template>
  <div style="position:relative" v-bind:class="{'open':openSuggestion}">
    <input class="form-control" type="text"
           v-model="text"
           @input="updateValue($event.target.value)"
           @keydown.enter='enter'
           @keydown.down='down'
           @keydown.up='up'
           @blur='resetText'
    >
    <ul class="dropdown-menu" style="width:100%">
      <li v-for="(suggestion, index) in matches"
          v-bind:class="{'active': isActive(index)}"
          @click="suggestionClick(index)"
      >
        <a href="#">{{ suggestion.name }}
          <small>{{ suggestion.id}}</small>
        </a>
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    props: {
      value: {
        type: Object,
        required: true
      },
      suggestions: {
        type: Array,
        required: true
      }
    },
    data () {
      return {
        text: "",
        open: false,
        current: 0
      }
    },
    computed: {
      // Filtering the suggestion based on the input
      matches () {
        return this.suggestions.filter((obj) => {
          return obj.name.indexOf(this.text) >= 0
        })
      },
      openSuggestion () {
        return this.selection !== '' &&
          this.matches.length !== 0 &&
          this.open === true
      }
    },
    methods: {
      updateValue (value) {
        if (this.open === false) {
          this.open = true
          this.current = 0
        }
      },
      // When enter pressed on the input
      enter () {
        this.$emit('input', this.matches[this.current])
        this.open = false
      },
      // When up pressed while suggestions are open
      up () {
        if (this.current > 0) {
          this.current--
        }
      },
      // When up pressed while suggestions are open
      down () {
        if (this.current < this.matches.length - 1) {
          this.current++
        }
      },
      // For highlighting element
      isActive (index) {
        return index === this.current
      },
      // When one of the suggestion is clicked
      suggestionClick (index) {
        this.$emit('input', this.matches[index])
        this.open = false
      },
      resetText() {
        this.text = this.value.name;
      },
    },
    mounted() {
      this.text = this.value.name;
    },
    watch: {
      value() {
        this.text = this.value.name;
      },
    },
  }
</script>

此外,似乎在打字时发出事件this.$emit('input', value) 是多余的。

【讨论】:

    猜你喜欢
    相关资源
    最近更新 更多
    热门标签