24-element-ui的input支持搜索和多tag标签

参考:https://blog.csdn.net/qq_36247432/article/details/88734522

效果图:

 

 

html代码

    <el-autocomplete
      class="inline-input"
      v-model="cSubcategoryNo"
      :fetch-suggestions="querySearch"
      placeholder="请输入内容"
      @select="handleSelect"
    ></el-autocomplete>
    <el-tag
      v-for="tag in selected"
      closable
      :disable-transitions="true"
      :key="tag"
      type="info"
      @close="handleClose(tag)"  # 定义了handleClose函数惨可以点击 ❌ 消除tag,这点官方文档好像有误
    >
      <span class="el-select__tags-text">{{ tag }}</span>
    </el-tag>

script代码  

<script>
  export default {
    data() {
      return {
        restaurants: [],
        cSubcategoryNo: '',   
        selected:[], // 获得value值
        selectedValue:[],  //获得code值
      };
    },
    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": "Hot honey 首尔炸鸡(仙霞路)", "address": "上海市长宁区淞虹路661号" },
          { "value": "新旺角茶餐厅", "address": "上海市普陀区真北路988号创邑金沙谷6号楼113" },
          { "value": "泷千家(天山西路店)", "address": "天山西路438号" },
          { "value": "胖仙女纸杯蛋糕(上海凌空店)", "address": "上海市长宁区金钟路968号1幢18号楼一层商铺18-101" },
          { "value": "贡茶", "address": "上海市长宁区金钟路633号" },
          { "value": "豪大大香鸡排超级奶爸", "address": "上海市嘉定区曹安公路曹安路1685号" },
          { "value": "茶芝兰(奶茶,手抓饼)", "address": "上海市普陀区同普路1435号" },
          { "value": "十二泷町", "address": "上海市北翟路1444弄81号B幢-107" },
          { "value": "星移浓缩咖啡", "address": "上海市嘉定区新郁路817号" },
          { "value": "阿姨奶茶/豪大大", "address": "嘉定区曹安路1611号" },
          { "value": "新麦甜四季甜品炸鸡", "address": "嘉定区曹安公路2383弄55号" },
         
          
        ];
      },
//多选栏中的删除
    handleClose(tag) {
      let item = this.selected.indexOf(tag);
        this.selected.splice(item, 1);
        this.selectedValue.splice(item, 1);
        console.log(this.selectedValue)
      },
//值
      handleSelect(item) {
        this.selected.push(item.value)
        this.selectedValue.push(item.address)
        this.cSubcategoryNo =""
        console.log(item);
      }
    },
    mounted() {
      this.restaurants = this.loadAll();
    }
  }
</script>

 

参考上面的结果以及这个组件(https://github.com/xiispace/el-input-tag/blob/master/src/ElInputTag.vue),实现了另外一种满足自己需求的样式如下,

和这个github上的组件相比,我这个的功能是支持搜索,结合了element-ui的autocomplete

同时参考了html的dom事件,参考:https://www.runoob.com/jsref/dom-obj-event.html

补充:有一个不带搜索的input-tag组件,链接:https://github.com/matiastucci/vue-input-tag

 

 

效果图:

代码如下:

<template>
  <div
    class="el-input-tag input-tag-wrapper"
    :class="[size ? 'el-input-tag--' + size : '']"
    @click="foucusTagInput">
    <el-tag
      v-for="(tag, idx) in innerTags"
      :key="tag"
      :size="size"
      :closable="!readOnly"
      :disable-transitions="false"
      @close="remove(idx)">
      {{tag}}
    </el-tag>
    <el-autocomplete
        v-model.trim="newTag"
        :fetch-suggestions="UserNameSearchAsync"
        placeholder="邮箱前缀"
        style="outline:none;      border:none;"
         @select = "handleSelect"
        clearable
        ></el-autocomplete>
  </div>
</template>

<script>
export default {
  name: 'ElInputTag',
  props: {
    value: {
      type: Array,
      default: () => []
    },
    addTagOnKeys: {
      type: Array,
      default: () => [13, 188, 9]
    },
    readOnly: {
      type: Boolean,
      default: false
    },
    size: String
  },
  data () {
    return {
      newTag: '',
      innerTags: [...this.value],
      dialog_temp: {},
    }
  },
  watch: {
    value () {
      this.innerTags = [...this.value]
    }
  },
  methods: {
    foucusTagInput () {
      if (this.readOnly || !this.$el.querySelector('.tag-input')) {
        return
      } else {
        this.$el.querySelector('.tag-input').focus()
      }
    },
    // handleSelect是自己实现的方法
    handleSelect(item) {
        let addSuucess = false
        if (this.addTag(this.newTag.trim())) {
          addSuucess = true
        }
        if (addSuucess) {
        this.tagChange()
        this.newTag = ''
      }
      console.log('value---1')
      console.log(this.innerTags)   // 选中的数据保存在了this.innerTags中,这个用来和后端交互
      console.log('value---2')

    },
    // addNew是https://github.com/xiispace/el-input-tag/blob/master/src/ElInputTag.vue上原先的方法
    addNew (e) {
      if (e && (!this.addTagOnKeys.includes(e.keyCode)) && (e.type !== 'blur')) {
        return
      }
      if (e) {
        e.stopPropagation()
        e.preventDefault()
      }
      let addSuucess = false
      if (this.newTag.includes(',')) {
        this.newTag.split(',').forEach(item => {
          if (this.addTag(item.trim())) {
            addSuucess = true
          }
        })
      } else {
        if (this.addTag(this.newTag.trim())) {
          addSuucess = true
        }
      }
      if (addSuucess) {
        this.tagChange()
        this.newTag = ''
      }
    },
    addTag (tag) {
      tag = tag.trim()
      if (tag && !this.innerTags.includes(tag)) {
        this.innerTags.push(tag)
        return true
      }
      return false
      
    },
    remove (index) {
      this.innerTags.splice(index, 1)
      this.tagChange()
      console.log('value---1')
      console.log(this.innerTags)
      console.log('value---2')
    },
    removeLastTag () {
      if (this.newTag) {
        return
      }
      this.innerTags.pop()
      this.tagChange()
    },
    tagChange () {
      this.$emit('input', this.innerTags)
    },

    // 下面两个方法是autocomplete相关的搜索方法
    UserNameSearchAsync(queryString, cb) {
      var username_list = [
              { key: 'admin_key', value: 'admin_value' },
              { key: 'wuxiaoyu', value: 'wuxiaoyu' },
              { key: 'wangguangshan', value: 'wangguangshan' },
          ];
      var results = queryString
        ? username_list.filter(this.createUserNameFilter(queryString))
        : username_list;

      clearTimeout(this.timeout);
      this.timeout = setTimeout(() => {
        cb(results);
      }, 100 * Math.random());
    },
    createUserNameFilter(queryString) {
      return state => {
        return (
          state.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0
        );
      };
    },
  }
}
</script>

<style scoped>
  .input-tag-wrapper {
    position: relative;
    font-size: 14px;
    background-color: #fff;
    background-image: none;
    border-radius: 4px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;
    color: #606266;
    display: inline-block;
    outline: none;
    padding: 0 10px 0 5px;
    transition: border-color .2s cubic-bezier(.645,.045,.355,1);
    width: 100%;
  }
  
  .el-tag {
    margin-right: 4px;
  }

  .tag-input {
    background: transparent;
    border: none!important;
    font-size: 14px;
    height: 40px;
    outline: none;
    padding-left: 0;
    width: 100px;
  }

  .el-input-tag--mini .tag-input{
    height: 28px;
    line-height: 28px;
  }

  .el-input-tag--small .tag-input{
    height: 32px;
    line-height: 32px;
  }

  .el-input-tag--medium .tag-input{
    height: 36px;
    line-height: 36px;
  }

  /* 下面这个的效果是autocomplete的input没有边框*/
  /deep/ input {
  /* input { */
    /* background-color: red!important;  调试用的样式 */
    outline:none!important;  
    border:none!important;
  }
</style>

 样式修改这块主要参考了 

自定义修改elementUI组件样式(贯穿样式)

https://zhuanlan.zhihu.com/p/29266022

https://www.jianshu.com/p/9caf9e7aaca4 

posted @ 2019-07-22 19:05  番茄土豆西红柿  阅读(10538)  评论(0编辑  收藏  举报
TOP