這篇文章主要介紹了Vue如何實(shí)現(xiàn)typeahead組件功能,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。
成都創(chuàng)新互聯(lián)堅(jiān)持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站建設(shè)、做網(wǎng)站、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時(shí)代的雅安網(wǎng)站設(shè)計(jì)、移動(dòng)媒體設(shè)計(jì)的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!Vue具體輕量級(jí)框架、簡(jiǎn)單易學(xué)、雙向數(shù)據(jù)綁定、組件化、數(shù)據(jù)和結(jié)構(gòu)的分離、虛擬DOM、運(yùn)行速度快等優(yōu)勢(shì),Vue中頁(yè)面使用的是局部刷新,不用每次跳轉(zhuǎn)頁(yè)面都要請(qǐng)求所有數(shù)據(jù)和dom,可以大大提升訪問(wèn)速度和用戶體驗(yàn)。
效果圖
實(shí)現(xiàn)的功能
1: 鼠標(biāo)點(diǎn)擊下拉框之外的區(qū)域關(guān)閉下拉框
2: 支持鍵盤(pán)上下鍵選擇,支持鼠標(biāo)選擇
3: 支持列表過(guò)濾搜索
4: 支持外部傳入列表JSON格式的映射
5: 支持placeholder的傳入
6: 選中對(duì)象的響應(yīng)(.sync vue2.3的組件通訊的語(yǔ)法糖)
7: 箭頭icon的映射,感覺(jué)作用不大,移除了
用法
<select-search placeholder="請(qǐng)選擇廣告主" :asyncData.sync="adHostData" :mapData="adHostDataList" :mapDataFormat="{label:'userName',value:'userId'}"> </select-search>
asyncData:響應(yīng)的數(shù)據(jù),也就是選中的..回來(lái)是一個(gè)對(duì)象
mapData : 搜索的列表數(shù)據(jù),肯定是外部傳入了…
mapData : 列表值映射
代碼
selectSearch.vue
<template> <div class="select-search" v-if="typeaheadData" ref="selectSearch" @click.native="showHideMenu($event)"> <div class="select-header"> <input type="text" autocomplete="off" readonly :placeholder="placeholder" :value="placeholderValue" @keydown.down.prevent="selectChildWidthArrowDown" @keydown.up.prevent="selectChildWidthArrowUp" @keydown.enter="selectChildWidthEnter"> <i class="fzicon " :class="isExpand?'fz-ad-jiantou1':'fz-ad-jiantou'"></i> </div> <div class="select-body" v-if="isExpand && typeaheadData"> <input type="text" placeholder="關(guān)鍵字" v-model="searchVal" autocomplete="off" @keydown.esc="resetDefaultStatus" @keydown.down.prevent="selectChildWidthArrowDown" @keydown.up.prevent="selectChildWidthArrowUp" @keydown.enter="selectChildWidthEnter"> <transition name="el-fade-in-linear" mode="out-in"> <div class="typeahead-filter"> <transition-group tag="ul" name="el-fade-in-linear" v-show="typeaheadData.length>0"> <li v-for="(item,index) in typeaheadData" :key="index" :class="item.active ? 'active':''" @mouseenter="setActiveClass(index)" @mouseleave="setActiveClass(index)" @click="selectChild(index)"> <a href="javascript:;" rel="external nofollow" > {{item[mapDataFormat.label]}} </a> </li> </transition-group> <p class="noFound" v-show="typeaheadData && typeaheadData.length === 0">未能查詢到,請(qǐng)重新輸入!</p> </div> </transition> </div> </div> </template> <script> export default { name: 'selectSearch', data: function () { return { placeholderValue: '',// 給看到選擇內(nèi)容的 isExpand: false, searchVal: '', // 搜索關(guān)鍵字 resultVal: '', // 保存搜索到的值 searchList: [], //保存過(guò)濾的結(jié)果集 currentIndex: -1, // 當(dāng)前默認(rèn)選中的index, } }, computed: { mapFormatData () { // 外部有傳入格式的時(shí)候映射mapData return this.mapData.map(item => { item[this.mapDataFormat.value] = item[this.mapDataFormat.value]; return item; }); }, typeaheadData () { let temp = []; if (this.searchVal && this.searchVal === '') { return this.mapFormatData; } else { this.currentIndex = -1; // 重置特殊情況下的索引 this.mapFormatData.map(item => { if (item[this.mapDataFormat.label].indexOf(this.searchVal.toLowerCase().trim()) !== -1) { temp.push(item) } return item; }) return temp; } } }, props: { placeholder: { type: String, default: '--請(qǐng)選擇--' }, emptyText: { type: String, default: '暫無(wú)數(shù)據(jù)' }, mapData: { // 外部傳入的列表數(shù)據(jù) type: Array, default: function () { return [] } }, mapDataFormat: { // 映射傳入數(shù)據(jù)的格式 type: Object, default: function () { return { label: 'text', value: 'value', extraText: 'extraText' } } }, asyncData: { // 實(shí)時(shí)響應(yīng)的值 type: [Object, String], default: function () { return {} } } }, methods: { showHideMenu (e) { // 點(diǎn)擊其他區(qū)域關(guān)閉下拉列表 if (e) { if (this.$refs.selectSearch && this.$refs.selectSearch.contains(e.target)) { this.isExpand = true; } else { this.isExpand = false; } } }, resetDefaultStatus () { // 清除所有選中狀態(tài) this.searchVal = ''; this.currentIndex = -1; this.typeaheadData.map(item => { this.$delete(item, 'active'); }) }, setActiveClass (index) { // 設(shè)置樣式活動(dòng)類 this.typeaheadData.map((item, innerIndex) => { if (index === innerIndex) { this.$set(item, 'active', true); this.currentIndex = index; // 這句話是用來(lái)修正index,就是鍵盤(pán)上下鍵的索引,不然會(huì)跳位 } else { this.$set(item, 'active', false) } }) }, selectChildWidthArrowDown () { // 判斷index選中子項(xiàng) if (this.currentIndex < this.typeaheadData.length) { this.currentIndex++; this.typeaheadData.map((item, index) => { this.currentIndex === index ? this.$set(item, 'active', true) : this.$set(item, 'active', false); }) } }, selectChildWidthArrowUp () { // 判斷index選中子項(xiàng) if (this.currentIndex > 0) { this.currentIndex--; this.typeaheadData.map((item, index) => { this.currentIndex === index ? this.$set(item, 'active', true) : this.$set(item, 'active', false); }) } }, selectChildWidthEnter () { // 若是結(jié)果集只有一個(gè),則默認(rèn)選中 if (this.typeaheadData.length === 1) { this.$emit('update:asyncData', this.typeaheadData[0]); // emit響應(yīng)的值 this.placeholderValue = this.typeaheadData[0][this.mapDataFormat.label]; } else { // 若是搜索的內(nèi)容完全匹配到項(xiàng)內(nèi)的內(nèi)容,則默認(rèn)選中 this.typeaheadData.map(item => { if (this.searchVal === item[this.mapDataFormat.label] || item.active === true) { this.$emit('update:asyncData', item); // emit響應(yīng)的值 this.placeholderValue = item[this.mapDataFormat.label]; } }) } this.isExpand = false; }, selectChild (index) { // 鼠標(biāo)點(diǎn)擊選擇子項(xiàng) this.typeaheadData.map((item, innerIndex) => { if (index === innerIndex || item.active) { this.placeholderValue = item[this.mapDataFormat.label]; this.$emit('update:asyncData', item); // emit響應(yīng)的值 } }); this.isExpand = false; }, }, mounted () { window.addEventListener('click', this.showHideMenu); }, beforeDestroy () { window.removeEventListener('click', this.showHideMenu); }, watch: { 'isExpand' (newValue) { if (newValue === false) { this.resetDefaultStatus(); } } } } </script> <style scoped lang="scss"> .el-fade-in-linear-enter-active, .el-fade-in-linear-leave-active, .fade-in-linear-enter-active, .fade-in-linear-leave-active { transition: opacity .2s linear; } .el-fade-in-enter, .el-fade-in-leave-active, .el-fade-in-linear-enter, .el-fade-in-linear-leave, .el-fade-in-linear-leave-active, .fade-in-linear-enter, .fade-in-linear-leave, .fade-in-linear-leave-active { opacity: 0; } .noFound { text-align: center; } .select-search { position: relative; z-index: 1000; a { color: #333; text-decoration: none; padding: 5px; } ul { list-style: none; padding: 6px 0; margin: 0; max-height: 200px; overflow-x: hidden; overflow-y: auto; li { display: block; width: 100%; padding: 5px; font-size: 14px; padding: 8px 10px; position: relative; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: #48576a; height: 36px; line-height: 1.5; box-sizing: border-box; cursor: pointer; &.active { background-color: #20a0ff; a { color: #fff; } } } } .select-header { position: relative; border-radius: 4px; border: 1px solid #bfcbd9; outline: 0; padding: 0 8px; >input { border: none; -webkit-appearance: none; -moz-appearance: none; appearance: none; width: 100%; outline: 0; box-sizing: border-box; color: #1f2d3d; font-size: inherit; height: 36px; line-height: 1; } >i { transition: all .3s linear; display: inline-block; position: absolute; right: 3%; top: 50%; transform: translateY(-50%); } } .select-body { position: absolute; border-radius: 2px; background-color: #fff; box-sizing: border-box; margin: 5px 0; padding: 8px; width: 100%; box-shadow: 0 2px 4px rgba(0, 0, 0, .12), 0 0 6px rgba(0, 0, 0, .04); >input { -webkit-appearance: none; -moz-appearance: none; appearance: none; background-color: #fff; background-image: none; border-radius: 4px; border: 1px solid #bfcbd9; box-sizing: border-box; color: #1f2d3d; font-size: inherit; height: 36px; line-height: 1; outline: 0; padding: 3px 10px; transition: border-color .2s cubic-bezier(.645, .045, .355, 1); width: 100%; display: inline-block; &:focus { outline: 0; border-color: #20a0ff; } } } } </style>
感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“Vue如何實(shí)現(xiàn)typeahead組件功能”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司,關(guān)注創(chuàng)新互聯(lián)成都網(wǎng)站設(shè)計(jì)公司行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來(lái)學(xué)習(xí)!
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、網(wǎng)站設(shè)計(jì)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)站標(biāo)題:Vue如何實(shí)現(xiàn)typeahead組件功能-創(chuàng)新互聯(lián)
URL分享:http://jinyejixie.com/article4/cshiie.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、虛擬主機(jī)、搜索引擎優(yōu)化、外貿(mào)建站、建站公司、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容