手機通訊錄,可模糊搜尋,點選字母定位,無需引用其他元件
阿新 • • 發佈:2019-02-20
公司需要個簡易通訊錄,自己就根據介面定義寫了個元件,支援手機號和工號模糊搜尋,開始用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> <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>
實際效果還不錯,如下: