国产99久久精品_欧美日本韩国一区二区_激情小说综合网_欧美一级二级视频_午夜av电影_日本久久精品视频

最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
當前位置: 首頁 - 科技 - 知識百科 - 正文

Vue實現(xiàn)typeahead組件功能(非常靠譜)

來源:懂視網 責編:小采 時間:2020-11-27 22:31:35
文檔

Vue實現(xiàn)typeahead組件功能(非常靠譜)

Vue實現(xiàn)typeahead組件功能(非常靠譜): 前言 之前那個typeahead寫的太早,不滿足當前的業(yè)務需求。 而且有些瑕疵,還有也不方便傳入數(shù)據和響應數(shù)據.. 于是就推倒了重來,寫了個V2的版本 看圖,多了一些細節(jié)的考慮;精簡了實現(xiàn)的邏輯代碼 效果圖 實現(xiàn)的功能 1: 鼠標點擊下拉框之外的區(qū)域關閉下拉框 2:
推薦度:
導讀Vue實現(xiàn)typeahead組件功能(非常靠譜): 前言 之前那個typeahead寫的太早,不滿足當前的業(yè)務需求。 而且有些瑕疵,還有也不方便傳入數(shù)據和響應數(shù)據.. 于是就推倒了重來,寫了個V2的版本 看圖,多了一些細節(jié)的考慮;精簡了實現(xiàn)的邏輯代碼 效果圖 實現(xiàn)的功能 1: 鼠標點擊下拉框之外的區(qū)域關閉下拉框 2:

 前言

之前那個typeahead寫的太早,不滿足當前的業(yè)務需求。

而且有些瑕疵,還有也不方便傳入數(shù)據和響應數(shù)據..

于是就推倒了重來,寫了個V2的版本

看圖,多了一些細節(jié)的考慮;精簡了實現(xiàn)的邏輯代碼

效果圖

這里寫圖片描述

實現(xiàn)的功能

1: 鼠標點擊下拉框之外的區(qū)域關閉下拉框

2: 支持鍵盤上下鍵選擇,支持鼠標選擇

3: 支持列表過濾搜索

4: 支持外部傳入列表JSON格式的映射

5: 支持placeholder的傳入

6: 選中對象的響應(.sync vue2.3的組件通訊的語法糖)

7: 箭頭icon的映射,感覺作用不大,移除了

用法

<select-search 
style="max-width:195px" 
placeholder="請選擇廣告主" 
:asyncData.sync="adHostData" 
:mapData="adHostDataList" 
:mapDataFormat="{label:'userName',value:'userId'}">
</select-search>
  • asyncData:響應的數(shù)據,也就是選中的..回來是一個對象
  • mapData : 搜索的列表數(shù)據,肯定是外部傳入了…
  • 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="關鍵字" 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">未能查詢到,請重新輸入!</p>
     </div>
     </transition>
     </div>
     </div>
    </template>
    <script>
     export default {
     name: 'selectSearch',
     data: function () {
     return {
     placeholderValue: '',// 給看到選擇內容的
     isExpand: false,
     searchVal: '', // 搜索關鍵字
     resultVal: '', // 保存搜索到的值
     searchList: [], //保存過濾的結果集
     currentIndex: -1, // 當前默認選中的index,
     }
     },
     computed: {
     mapFormatData () { // 外部有傳入格式的時候映射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: '--請選擇--'
     },
     emptyText: {
     type: String,
     default: '暫無數(shù)據'
     },
     mapData: { // 外部傳入的列表數(shù)據
     type: Array,
     default: function () {
     return []
     }
     },
     mapDataFormat: { // 映射傳入數(shù)據的格式
     type: Object,
     default: function () {
     return {
     label: 'text',
     value: 'value',
     extraText: 'extraText'
     }
     }
     },
     asyncData: { // 實時響應的值
     type: [Object, String],
     default: function () {
     return {}
     }
     }
     },
     methods: {
     showHideMenu (e) { // 點擊其他區(qū)域關閉下拉列表
     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) { // 設置樣式活動類
     this.typeaheadData.map((item, innerIndex) => {
     if (index === innerIndex) {
     this.$set(item, 'active', true);
     this.currentIndex = index; // 這句話是用來修正index,就是鍵盤上下鍵的索引,不然會跳位
     } else {
     this.$set(item, 'active', false)
     }
     })
     },
     selectChildWidthArrowDown () {
     // 判斷index選中子項
     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選中子項
     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 () {
     // 若是結果集只有一個,則默認選中
     if (this.typeaheadData.length === 1) {
     this.$emit('update:asyncData', this.typeaheadData[0]); // emit響應的值
     this.placeholderValue = this.typeaheadData[0][this.mapDataFormat.label];
     } else {
     // 若是搜索的內容完全匹配到項內的內容,則默認選中
     this.typeaheadData.map(item => {
     if (this.searchVal === item[this.mapDataFormat.label] || item.active === true) {
     this.$emit('update:asyncData', item); // emit響應的值
     this.placeholderValue = item[this.mapDataFormat.label];
     }
     })
     }
     this.isExpand = false;
     },
     selectChild (index) {
     // 鼠標點擊選擇子項
     this.typeaheadData.map((item, innerIndex) => {
     if (index === innerIndex || item.active) {
     this.placeholderValue = item[this.mapDataFormat.label];
     this.$emit('update:asyncData', item); // emit響應的值
     }
     });
     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>

    總結

    以上所述是小編給大家介紹的Vue實現(xiàn)typeahead組件功能(非常靠譜),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

    聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

    文檔

    Vue實現(xiàn)typeahead組件功能(非常靠譜)

    Vue實現(xiàn)typeahead組件功能(非常靠譜): 前言 之前那個typeahead寫的太早,不滿足當前的業(yè)務需求。 而且有些瑕疵,還有也不方便傳入數(shù)據和響應數(shù)據.. 于是就推倒了重來,寫了個V2的版本 看圖,多了一些細節(jié)的考慮;精簡了實現(xiàn)的邏輯代碼 效果圖 實現(xiàn)的功能 1: 鼠標點擊下拉框之外的區(qū)域關閉下拉框 2:
    推薦度:
    標簽: VUE 靠譜 非常
    • 熱門焦點

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 一道本在线 | 全黄网站 | 欧美高清亚洲欧美一区h | 纯毛片 | 成人看的一级毛片 | 一区二区三区在线免费 | 国产视频久久 | 欧美成人高清在线视频大全 | 亚欧在线观看 | 国产对白在线播放九色 | 在线播放真实国产乱子伦 | 日本不卡视频一区二区 | 亚洲乱码中文论理电影 | 国产aaaaa一级毛片无下载 | 免费一级 一片一毛片 | 亚洲第一视频区 | 偷拍第一页 | 日韩免费一区二区三区 | 欧美日韩在线精品一区二区三区 | 中文字幕第一页亚洲 | 蜜桃视频一区二区三区四区 | 精品一区二区在线欧美日韩 | 欧美日韩国产精品综合 | 欧美日韩视频一区二区在线观看 | 91精品久久久久久久久久 | 亚洲 欧美 日韩 在线 | 日本久久香蕉一本一道 | 香港一级a毛片在线播放 | 国产日韩在线看 | 2021国产精品成人免费视频 | b毛片| 亚洲成人精品久久 | 真人一级一级毛片免费观看 | 日韩成人在线电影 | 亚洲精品99久久久久中文字幕 | 亚洲欧美日韩中文字幕在线不卡 | 国产精品123区 | 激情另类国内一区二区视频 | 国模沟沟一区二区三区 | 91精品专区 | 日韩欧美国产高清 |