天天看點

基于Material實作下拉框多選并且可點選“x”删除(Chips)

基于Material實作下拉框多選并且可點選“x”删除(Chips)

    • 需求
    • 實作
    • 寫在最後

需求

近期在使用Material搭建一個背景系統,遇到一個如下需求:

基于Material實作下拉框多選并且可點選“x”删除(Chips)

功能需求如下:輸入框擷取焦點時彈出下拉框,下拉框同時支援多選,選中的值會以Material提供的chips的形式顯示在輸入框的前部,同時chips要支援可點選“x”删除,其實這個需求還是蠻常見的,就是一個支援模糊搜尋的多選下拉框,但是我找遍了Material的官方文檔也沒找到這個功能的api或代碼段,官方文檔倒是有chips但是不支援下拉框,有下拉框但是不支援多選,有多選但是又不支援chips,隻好自己手動把這三個功能實作在一起了。

基于Material實作下拉框多選并且可點選“x”删除(Chips)

實作

檢視Material的官方文檔很快就可以找到這樣一個代碼段:chips

基于Material實作下拉框多選并且可點選“x”删除(Chips)

功能與我們想要實作的需求有部分類似,于是我就想以這個官方功能為基礎進行擴充,還需要擴充的功能如下:彈出下拉框,支援多選并指派,同時失去焦點隐藏下拉框,話不多說,Show me the code:

<template>
  <div class="">
    <div class="closeArea"
         v-show="showCustomInput"
         @click="showCustomInput = false">

    </div>
    <div class="CustomInput">
      <div class="md-field md-theme-default"
           :class="{'md-focused':isFocus,'md-has-value':chipsArr.length!=0}">
        <label for="md-input-34pnj2lffo">成員</label>
        <div class="chipsIn">
          <md-chip
            v-for="item in chipsArr"
            md-deletable @md-delete="testCons">
            {{item.name}}
          </md-chip>
          <input
            @focus="inputFocusAction"
            @blur="inputBlurAction"
            type="text" id="md-input-34pnj2lffo" class="md-input">
        </div>
        <!--<i class="md-icon md-icon-font cur md-theme-default">-->
        <!--<i class="fa fa-sort-amount-desc filter_icon"></i>-->
        <!--</i>-->
      </div>
      <div class="drop_down_area" v-show="showCustomInput">
        <ul>
          <li v-for="item in chipsArr"
              @click="addArr(item)">{{item.name}}</li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
  import {mapGetters} from 'vuex'

  export default {
    data() {
      return {
        isFocus: false,
        showCustomInput: false,
        chipsArr: [{
          index: 0,
          name: "Deletable0"
        }, {
          index: 1,
          name: "Deletable1"
        }, {
          index: 2,
          name: "Deletable2"
        }, {
          index: 0,
          name: "Deletable0"
        }, {
          index: 1,
          name: "Deletable1"
        }, {
          index: 2,
          name: "Deletable2"
        },],
      }
    },
    computed: {
      ...mapGetters([
        '',
      ])
    },
    created() {

    },
    methods: {
      testCons() {
        this.chipsArr.splice(0,1)
      },
      addArr(item){
        this.chipsArr.push(item)
      },
      inputFocusAction(){
        this.isFocus = true;
        this.showCustomInput = true;
      },
      inputBlurAction(){
        this.isFocus = false;
      },
    }
  }
</script>

<style lang="scss" scoped>
  .closeArea{
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
  }

  //自定義複選下拉框樣式
  .CustomInput {
    position: relative;
    .md-chip {
      float: left;
      height: 24px;
      line-height: 24px;
      margin: 4px 4px 0 0;
    }
    .md-field {
      display: block;
    }
    .chipsIn {
      max-height: 300px;
      overflow-y: scroll;
    }
    .md-input {
      width: 130px;
    }
    .drop_down_area::-webkit-scrollbar{
      width: 0;
    }
    .drop_down_area {
      width: 100%;
      height: 200px;
      background-color: #fff;
      position: absolute;
      left: 0;
      top: 100%;
      overflow-y: scroll;
      border: 1px solid #E7E7E7;
      z-index: 7;
      ul {
        li {
          width: 100%;
          height: 32px;
          line-height: 32px;
          padding-left: 20px;
          cursor: pointer;
          transition: .3s cubic-bezier(.25, .8, .25, 1);
          &:hover {
            background-color: #D5E3F6;
          }
        }
      }
    }
  }
</style>

           

其實實作起來還是蠻簡單的,主要是Material竟然不提供這個功能着實很讓人無助,(其實還有很多大衆需求都不怎麼支援,我将在後續文檔繼續介紹,不過也不能怪Material,畢竟這是一款移動端插件,而且閱聽人國内開發者确實不多。)

寫在最後

希望這篇文檔能給您帶來幫助,感謝閱讀。