1. 程式人生 > >手機通訊錄,可模糊搜尋,點選字母定位,無需引用其他元件

手機通訊錄,可模糊搜尋,點選字母定位,無需引用其他元件

公司需要個簡易通訊錄,自己就根據介面定義寫了個元件,支援手機號和工號模糊搜尋,開始用a和id錨點定位,但是會影響路由跳轉,最後改用scrollTop offsetHeight來解決,程式碼如下

<template>
  <div class="worker">
    <transition name="fade">
      <div class="showWord" v-show="word!=''">{{word}}</div>
    </transition>
    <div class="mui-input-row mui-search">
      <input type="search" v-model="searchKey" class="mui-input-clear" placeholder="請輸入教職工號、姓名、車牌號">
    </div>

    <div class="workerList" ref="workList">
      <template>
        <div class="menu" v-for="cate in searchRes" v-if="searchRes.length>0">
          <div class="menu-tip" :id="cate.category">
            {{cate.category}}
          </div>
          <ul class="mui-clearfix">
            <li v-for="worker in cate.workers" @click="selectWorker(worker)">
              <img v-lazy="worker.avatar_url"/>
              <div>
                <p><span style="font-size: 16px;color:#000">{{worker.name}}</span>&nbsp;&nbsp;&nbsp;&nbsp;<span
                  style="font-size: 13px;color:#999">{{worker.unified_id}}</span></p>
                <p><span style="font-size: 15px;color:#666">{{worker.phone}}</span></p>
              </div>
            </li>
          </ul>
        </div>
        <div class="categoryList" v-if="searchRes.length>0">
          <div v-for="categ in searchRes" @click="goCategory(categ.category)">
            <a>
              {{categ.category}}
            </a>
          </div>
        </div>
      </template>
    </div>
  </div>
</template>

<script>
  export default {
    name: "worker",
    data() {
      return {
        word: '',
        setTime: '',
        searchKey: '',
        searchRes: [],
        //dataRes資料格式 [
          {cagegory:'A',workers:[]},
          {cagegory:'B',workers:[]},
        ]
        dataRes: []
      }
    },
    methods: {
      getWorkers: function () {
        let that = this
        that.utils.axiosGet('device/app/staff', {params: that.req}, function (success) {
          if (success.data.error_code == '1000') {
            that.dataRes = success.data.extra.data
            that.searchRes = that.dataRes
          } else {
            mui.toast(success.data.error_msg)
          }
        }, function (error) {
          mui.toast('網路錯誤')
        })
      },
      goCategory: function (id) {
        //scrollTop小於0或大於最大值時預設正常值
        this.$refs.workList.scrollTop = document.getElementById(id).offsetTop - this.$refs.workList.offsetHeight / 2
        this.showWord(id)
      },
      showWord: function (e) {
        let that = this
        that.word = e
        //每次都要清除計時器 否則會影響下一次
        clearTimeout(that.setTime)
        that.setTime = setTimeout(function () {
          that.word = ''
        }, 1500)
      },
      createSearchRes: function (item, worker) {
        let that = this
        let flag = true
        that.searchRes.filter(function (searchItem) {
          if (searchItem.category == item.category) {
            //如果沒有這個category表示陣列沒有這個物件 需要新建
            flag = false
            searchItem.workers.push(worker)
          }
        })
        if (flag) {
          that.searchRes.push({category: item.category, workers: [worker]})
        }
      },
      selectWorker: function (worker) {
        this.utils.putSessionItem('worker', worker)
        this.$router.go(-1)
      }
    },
    watch: {
      searchKey(keyWord) {
        console.log(keyWord)
        let that = this
        that.searchRes = []
        if (keyWord == '') {
          that.searchRes = that.dataRes
          return
        }
        that.dataRes.filter(function (item) {
          for (let i = 0; i < item.workers.length; i++) {
            if (item.workers[i].unified_id.indexOf(keyWord) > -1) {
              that.createSearchRes(item, item.workers[i])
              continue
            }
            if (item.workers[i].name.indexOf(keyWord) > -1) {
              that.createSearchRes(item, item.workers[i])

            }
          }
        })
        console.log(that.searchRes)
      }
    },
    mounted() {
      this.getWorkers()
    }
  }
</script>

<style scoped>
  .worker {
    width: 100%;
    height: 100%;
    padding: 10px 10px 2px 10px;
    box-sizing: border-box;
    position: relative;
    background: #fff;
  }

  .showWord {
    width: 120px;
    height: 120px;
    border-radius: 50%;
    position: absolute;
    top: calc(50% - 60px);
    left: calc(50% - 60px);
    border: 5px solid white;
    color: black;
    box-shadow: 0 0 50px 1px #aaa inset, 0 0 20px 1px #999;
    background: rgba(0, 0, 0, 0.05);
    text-align: center;
    line-height: 110px;
    font-size: 50px;
    font-weight: bold;
  }

  .fade-enter-active, .fade-leave-active {
    opacity: 1;
    transition: opacity .5s;
  }

  .fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */
  {
    opacity: 0;
  }

  .mui-search {
    height: 50px;
  }

  .workerList {
    width: 100%;
    height: calc(100% - 50px);
    overflow-y: auto;
    border-radius: 10px;
  }

  .workerList::-webkit-scrollbar { /*隱藏滾輪*/
    display: none;
  }

  .menu {
    width: 96%;
    margin: 10px 2% 0 2%;
  }

  .menu-tip {
    width: 100%;
    height: 30px;
    line-height: 30px;
    font-size: 18px;
    color: #4FACFE;
  }

  .menu ul {
    width: 100%;
    padding: 0;
    margin: 0;
    list-style-type: none;
  }

  .menu ul li {
    width: 100%;
    height: 60px;
    margin: 10px 0 0 0;
    padding: 0;
  }

  .menu ul li img {
    float: left;
    width: 60px;
    height: 60px;
    border-radius: 50%;
  }

  .menu ul li div {
    float: right;
    width: calc(100% - 80px);
    height: 60px;
  }

  .menu ul li div p {
    width: 100%;
    height: 26px;
    line-height: 26px;
    margin: 0;
  }

  .categoryList {
    position: fixed;
    display: flex;
    flex-direction: column;
    justify-content: space-around;
    width: 30px;
    bottom: 3px;
    right: 1px;
    border-radius: 5px;
    height: calc(100% - 60px);
    background: #999;
    z-index: 100;
  }

  .categoryList div {
    width: 30px;
    line-height: 20px;
    text-align: center;
  }

  .categoryList a {
    color: white;
    font-size: 14px;
  }
</style>

實際效果還不錯,如下: