用vuejs打造auto complete input

数据定义

data () {
    return {
      data: '', // 绑定到input的数据
      dataList: [ // 预设值数组
        'pascal', 'php', 'nodejs', 'vuejs', 'reactjs'
      ],
      maxCount: 8, //补全输入最大显示数字
      matchList: [], //匹配输入值的数组
      matchListIndex: null //匹配输入值数组的索引
    }
},

html模板

这里只做了三件事情
- 先建立个简单的html模板
- 绑定tag到输入框,循环matchTags的内容到面板上。
- 添加CSS样式。

<template>
<div>
  <input 
    v-model="data"
    placeholder="enter things..."
    />
  <div>
    <li v-for="(item, index) in matchList">
      <p 
        :class="{'item-selected': isSelected(index)}">
      {{item}}</p>
    </li>
  </div>
</div>
</template>

<style scoped>
.item-selected {
  background: #41B883;
  color: #FFF }
</style>

方法定义

methods: {
    // 设置autocomplete面板内容
    setMatchList () {
      if (this.matchListIndex === null) {
        if (this.data === '') {
          this.matchList = []
          return
        }
        let matchData = this.dataList.filter(v => v.indexOf(this.data) > -1)
        this.matchList = matchData.slice(0, this.maxCount)
      }
    },
    // 直接设置MatchListIndex
    setMatchListIndex (index) {
      this.matchListIndex = index
    },
    // 计算MatchIndex
    calMatchListIndex (param) {
      if (this.matchListIndex === null) {
        this.matchListIndex = 0
        return
      }
      if (this.matchListIndex + param >= this.matchList.length) {
        this.matchListIndex = null
        return
      }
      if (this.matchListIndex + param < 0) {
        this.matchListIndex = 0
        return
      }
      this.matchListIndex = this.matchListIndex + param
    },
    // 判断是否是选中的项
    isSelected (index) {
      return index === this.matchListIndex
    },
    // 重置匹配列表
    resetMatchList () {
      this.matchListIndex = null
      this.matchList = []
      this.setMatchList()
    },
    // 清空匹配列表
    clearMatchList () {
      this.matchList = []
    }
  }

数据监听

watch: {
    data () {
      if (this.matchList[this.matchListIndex] !== this.data) {
        this.resetMatchList()
      }
    },
    matchListIndex () {
      if (this.matchListIndex !== null) {
        this.data = this.matchList[this.matchListIndex]
      }
    }
},

绑定监听事件

代码说明:
- @keyup.down和@keyup.up是键盘上下按钮时修改matchListIndex的值,macthListIndex是监听计算的,修改时会赋值当前选中的值到input
- 点击输入框的时候从新计算匹配值
- @mouseenter是匹配值hover时修改input的效果
- @blur是失去焦点后清空匹配数组

<template>
<div>
  <input 
    v-model="data"
    placeholder="enter things..."
    @keyup.down="calMatchListIndex(1)" 
    @keyup.up="calMatchListIndex(-1)" 
    @click="resetMatchList"
    @blur="clearMatchList"
    />
  <div>
    <li v-for="(item, index) in matchList">
      <p 
        :class="{'item-selected': isSelected(index)}"
        @mouseenter="setMatchListIndex(index)">
      {{item}}</p>
    </li>
  </div>
</div>
</template>

总结

That is it!

附上github地址:https://github.com/pascallin/vue-autocomplete-input

Logo

前往低代码交流专区

更多推荐