天天看點

基于Material實作可搜尋的下拉框

基于Material實作可搜尋的下拉框

    • 需求
    • 寫在最後

需求

近期在使用Material的過程中遇到如下需求:需要實作可搜尋的下拉框,并且點選選項實作指派:

基于Material實作可搜尋的下拉框

周遊Material的官方文檔也沒找到這個完整功能的api,找到了類似的下拉框:

基于Material實作可搜尋的下拉框

于是就想基于這個官方文檔的類似功能實作我們所需要的支援搜尋的下拉框,下面貼上改造後的代碼:

<template>
  <div class="addMembers">
    <div class="closeArea"
         v-show="isFocused"
         @click="changeFocused">

    </div>
    <ul>
      <li class="clearfix" v-for="(ite,ind) in overallArr">
        <div class="fl memberList membersLi">
          <div class="md-field md-theme-default"
               :class="{'md-focused md-highlight':ite[0].value!='' || ite[0].flag}"
               @click="allFalse();ite[0].flag = true;isFocused = true">
            <label for="country">{{ite[0].value?'角色':'請選擇一個角色'}}</label>
            <div class="md-menu md-select">
              <input type="text" v-model="ite[0].value" name="country" readonly="readonly"
                     class="md-input md-input md-select-value">
              <i class="md-icon md-icon-font md-icon-image md-theme-default">
                <svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
                  <path d="M7 10l5 5 5-5z"></path>
                  <path d="M0 0h24v24H0z" fill="none"></path>
                </svg>
              </i>
            </div>
          </div>
          <div class="selectList" v-show="ite[0].flag">
            <div class="search">
              <i class="fa fa-search fa-lg search_icon lmr cur"></i>
              <input type="text" class="search_input" placeholder="admin">
            </div>
            <div class="search_content">
              <ul class="zeroY">
                <li v-for="(item,index) in memberList" @click="changeValue(item,0,ind)">{{item}}</li>
              </ul>
            </div>
            <div class="bottom_management">
              <a href="javascript:;" class="backLink">管理角色</a>
            </div>
          </div>
        </div>
        <div class="fl dataList membersLi">
          <div class="md-field md-theme-default"
               :class="{'md-focused md-highlight':ite[1].value!='' || ite[1].flag}"
               @click="allFalse();ite[1].flag = true;isFocused = true">
            <label for="country">{{ite[1].value?'資料集':'請選擇一個資料集'}}</label>
            <div class="md-menu md-select">
              <input type="text" v-model=" ite[1].value" name="country" readonly="readonly"
                     class="md-input md-input md-select-value">
              <i class="md-icon md-icon-font md-icon-image md-theme-default">
                <svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
                  <path d="M7 10l5 5 5-5z"></path>
                  <path d="M0 0h24v24H0z" fill="none"></path>
                </svg>
              </i>
            </div>
          </div>
          <div class="selectList" v-show=" ite[1].flag">
            <div class="search">
              <i class="fa fa-search fa-lg search_icon lmr cur"></i>
              <input type="text" class="search_input" placeholder="admin">
            </div>
            <div class="search_content">
              <ul class="zeroY">
                <li v-for="(item,index) in memberList" @click="changeValue(item,1,ind)">{{item}}</li>
              </ul>
            </div>
            <div class="bottom_management">
              <a href="javascript:;" class="backLink">管理角色</a>
            </div>
          </div>
        </div>
        <i class="fa fa-trash fa-lg trash_icon lmr cur" @click="deleteMember(ind)"></i>
      </li>
    </ul>
  </div>
</template>

<script>

  export default {
    data() {
      return {
        timeFlag: false,
        isFocused: false,
        changeBackgroundColor: false,
        initial: "",
        country: "",
        memberValue: "",
        memberList: [
          'Orange',
          'Apple',
          'Pineapple',
          'Orange1',
          'Apple1',
          'Pineapple1',
          'Orange2',
          'Apple2',
          'Pineapple2',
          'Orange',
          'Apple',
          'Pineapple',
          'Orange1',
          'Apple1',
          'Pineapple1',
          'Orange2',
          'Apple2',
          'Pineapple2',
        ],
        dataList: [
          'Orange',
          'Apple',
          'Pineapple',
          'Orange1',
          'Apple1',
          'Pineapple1',
          'Orange2',
          'Apple2',
          'Pineapple2',
        ],
        singularArr: [{
          value: "",
          flag: false,
        }, {
          value: "",
          flag: false,
        }],
        overallArr: [[
          {
            value: "",
            flag: false,
          }, {
            value: "",
            flag: false,
          }
        ]],
      }
    },
    created() {

    },
    methods: {
      changeFocused() {
        let that = this;
        that.isFocused = false;
        that.allFalse();
      },
      changeValue(value, index, ind) {
        let that = this;
        let canPush = false;
        that.overallArr[ind][index].flag = false;
        that.overallArr[ind][index].value = value;
        that.isFocused = false;
//        判斷是否允許添加,如果兩條/一條資訊全部選擇,就添加,否則不添加
        for (var i = 0; i < that.overallArr.length; i++) {
          that.overallArr[i][0].value ? canPush = true : canPush = false;
          canPush?that.dataList.length == 0 ? "" :
            (that.overallArr[i][1].value ? canPush = true : canPush = false):"";
          if(!canPush){
            break
          }
        }
        console.log(that.overallArr);
        canPush ? that.overallArr.push([{
          value: "",
          flag: false,
        }, {
          value: "",
          flag: false,
        }]) : ""
      },
      allFalse() {
        let that = this;
        that.overallArr.forEach(function (val, ind) {
          val.forEach(function (value, index) {
            value.flag = false
          })
        })
      },
      deleteMember(index){
        console.log(index);
        this.overallArr.splice(index,1)
      },
      reset(){
        this.changeFocused()
      },
    }
  }
</script>

<style lang="scss" scoped>
  .addMembers {
    margin-top: 25px;
    width: 100%;
    .md-icon.md-theme-default.md-icon-image svg {
      fill: #999;
    }
    ul {
      li {
        margin-bottom: 20px;
        position: relative;
        .trash_icon {
          position: absolute;
          right: -40px;
          top: 28px;
          font-size: 18px;
        }
        .memberList {
          margin-right: 2%;
        }
        .membersLi {
          width: 49%;
          position: relative;
          .selectList {
            width: 100%;
            max-height: 403px;
            background-color: #fff;
            position: absolute;
            left: 0;
            top: 100%;
            border: 1px solid #E7E7E7;
            z-index: 7;
            .search {
              width: 100%;
              height: 50px;
              line-height: 50px;
              border-bottom: 1px solid #E7E7E7;
              background-color: #FAFAFA;
              padding-left: 20px;
              .search_input {
                background-color: #FAFAFA;
                height: 20px;
              }
            }
          }
          .search_content::-webkit-scrollbar {
            width: 0;
          }
          .search_content {
            max-height: 290px;
            overflow: scroll;
            margin-bottom: 55px;
            ul {
              li {
                width: 100%;
                height: 28px;
                line-height: 28px;
                transition: .3s cubic-bezier(.25, .8, .25, 1);
                cursor: pointer;
                font-size: 13px;
                padding-left: 15px;
                margin-bottom: 0;
                &:hover {
                  background-color: #F7F7F7;
                }
              }
            }
          }
          .bottom_management {
            border-top: 1px solid #E7E7E7;
            width: 100%;
            height: 50px;
            line-height: 50px;
            position: absolute;
            left: 0;
            bottom: 0;
            padding-left: 20px;
          }
        }
      }
    }
  }

</style>

           

實作起來還是比較簡單的,不過是添加了一個搜尋框而已,然後動态地去改變下方li标簽的内容罷了,注意,代碼中使用到了字型圖示庫font awesome,在這裡還是要強推一下這個字型圖示庫,很全而且上手也很簡單。下面看一下實作後的效果:

基于Material實作可搜尋的下拉框

寫在最後

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