• <fieldset id="8imwq"><menu id="8imwq"></menu></fieldset>
  • <bdo id="8imwq"><input id="8imwq"></input></bdo>
    最新文章專題視頻專題問答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實現typeahead組件功能(非常靠譜)

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

    Vue實現typeahead組件功能(非??孔V)

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

     前言

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

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

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

    看圖,多了一些細節的考慮;精簡了實現的邏輯代碼

    效果圖

    這里寫圖片描述

    實現的功能

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

    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:響應的數據,也就是選中的..回來是一個對象
  • mapData : 搜索的列表數據,肯定是外部傳入了…
  • 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: '暫無數據'
     },
     mapData: { // 外部傳入的列表數據
     type: Array,
     default: function () {
     return []
     }
     },
     mapDataFormat: { // 映射傳入數據的格式
     type: Object,
     default: function () {
     return {
     label: 'text',
     value: 'value',
     extraText: 'extraText'
     }
     }
     },
     asyncData: { // 實時響應的值
     type: [Object, String],
     default: function () {
     return {}
     }
     }
     },
     methods: {
     showHideMenu (e) { // 點擊其他區域關閉下拉列表
     if (e) {
     if (this.$refs.selectSearch && this.$refs.selectSearch.contains(e.target)) {
     this.isExpand = true;
     } else {
     this.isExpand = false;
     }
     }
     },
     resetDefaultStatus () { // 清除所有選中狀態
     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實現typeahead組件功能(非常靠譜),希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

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

    文檔

    Vue實現typeahead組件功能(非??孔V)

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

    最新推薦

    猜你喜歡

    熱門推薦

    專題
    Top
    主站蜘蛛池模板: 四虎影永久在线观看精品| 精品无人区无码乱码大片国产| 国产精品igao视频网| 国产精品午夜久久| 2022免费国产精品福利在线| 欧美亚洲另类精品第一页| 国产精品第13页| 久久香蕉国产线看观看精品yw| 久久99精品久久久久久hb无码 | 日韩精品一二三四区| 久久精品国产一区| 国产精品亚韩精品无码a在线| 欧美精品/日韩精品/国产精品| 国产精品va在线观看无码| 99国产精品国产精品九九| 中文字幕精品无码一区二区三区| 国产成人精品一区二区三区免费| 亚洲欧洲国产日韩精品| 3D动漫精品啪啪一区二区下载| 成人精品一区二区久久久| 国内精品51视频在线观看| 久久香蕉超碰97国产精品| 亚洲国产精品无码一线岛国| 亚洲国产精品成人一区| 九色精品视频在线观看| 精品久久久久久无码中文野结衣 | 欧美精品三区| 国产久爱免费精品视频| 欧美日韩精品一区二区三区| 国产99re在线观看只有精品| 久久99国产综合精品| 麻豆aⅴ精品无码一区二区| 午夜精品久久久久久中宇| 亚洲αv在线精品糸列 | 老司机性色福利精品视频| 亚洲精品国产日韩无码AV永久免费网 | 国产精品推荐天天看天天爽| 国产精品免费一区二区三区| 国产精品污WWW一区二区三区| 国精无码欧精品亚洲一区| 国产成人精品无码片区在线观看|