el-autocomplete组件封装

4,005 阅读2分钟

el-autocomplete介绍

el-autocomplete 是elementUI组件库中的一个可带输入建议的输入框组件。它的功能分为两部分:

  • 输入的同时调用后台匹配数据,可从返回的结果中像select框一样选择你想输入的数据
  • 如果没有匹配到你想输入的数据,可以像input框一样输入

以下是根据官网上的示例封装了一个itable组件

<template>
  <div>
    <el-row class="demo-autocomplete">
      <el-col :span="12">
        <div class="sub-title">输入后匹配输入建议</div>
        <el-autocomplete
          class="inline-input"
          v-model="state2"
          :fetch-suggestions="querySearch"
          placeholder="请输入内容"
          :trigger-on-focus="false"
          @select="handleSelect"
        ></el-autocomplete>
      </el-col>
    </el-row>
  </div>
</template>
<script>
export default {
  data() {
    return {
      restaurants: [],
      state2: ""
    };
  },
  props:{
    state:{
      type:String
    }
  },
  methods: {
    querySearch(queryString, cb) {
      var restaurants = this.restaurants;
      var results = queryString
        ? restaurants.filter(this.createFilter(queryString))
        : restaurants;
      // 调用 callback 返回建议列表的数据
      cb(results);
    },
    createFilter(queryString) {
      return restaurant => {
        return (
          restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) ===
          0
        );
      };
    },
    loadAll() {
      return [
        { value: "三全鲜食(北新泾店)", address: "长宁区新渔路144号" },
        { value: "NONO JUICE  鲜榨果汁", address: "上海市长宁区天山西路119号" },
        { value: "CoCo都可(北新泾店)", address: "上海市长宁区仙霞西路" },
        { value: "枪会山", address: "上海市普陀区棕榈路" },
        { value: "纵食", address: "元丰天山花园(东门) 双流路267号" },
        { value: "钱记", address: "上海市长宁区天山西路" },
        { value: "壹杯加", address: "上海市长宁区通协路" },
        { value: "超级鸡车(丰庄路店)", address: "上海市嘉定区丰庄路240号" },
        { value: "妙生活果园(北新泾店)", address: "长宁区新渔路144号" },
        { value: "香宜度麻辣香锅", address: "长宁区淞虹路148号" },
        { value: "壹分米客家传统调制米粉(天山店)", address: "天山西路428号" },
        { value: "红辣椒麻辣烫", address: "上海市长宁区天山西路492号" },
        { value: "阳阳麻辣烫", address: "天山西路389号" }
      ];
    },
    handleSelect(item) {
      this.state2 = item.value
      this.$emit('input',this.state2)
    }
  },
  mounted() {
    this.restaurants = this.loadAll();
  }
};
</script>

遇到的坑

通过输入建议,确实可以在父组件获取到对应的数据,比如在输入框输入 “三”,就会弹出“三全鲜食(北新泾店)”,选中即可选择;但是如果是自己输入的数据,这时在父组件就获取不到值。原来,select事件只是通过输入建议输入值触发的事件,自己输入数据是不会触发的,因此自己输入的值在父组件获取不到。为了解决这个问题,先是试了一下change事件,发现没有效果,于是只能自己手动对state2设计一个监听,当state2发生变化的时候触发emit事件,而从父组件就可以获取到值了。

  methods: {
    handleSelect(item) {
      this.state2 = item.value
    }
  },
  watch: {
    state2: {
      immediate: true,
      handler(val) {
        this.$emit('input',val)
      }
    }
  }

后记

试想,如果elementUI在这个组件上提供一个change事件,通过change事件触发emit,这样封装组件的时候就更方便啦~