最近在使用iview重構老項目頁面代碼的時候,發現老項目有部分下拉框既能夠編輯又能夠選擇下拉框自帶的內容,找了找iview的select組件,發現並無一個相似的功能。javascript
最接近個人需求的,多是設置select的filterable屬性開啓搜索模式,可是每次輸入新的內容,鼠標一離開不是被清空,就是選中以前選擇的一項,故放棄。css
後來又看到iview4.0的版本加了一個allow-create屬性,拿給老大看了下,他以爲太麻煩了,不夠簡潔,首先是必須輸完自定義的內容後,必定要點下圖的箭頭或者按回車,才能將內容加到列表。html
另外就是以爲必定要把自定義的內容加到列表中,總以爲不舒服(不是我以爲啊),所以放棄。vue
對select抱有一絲但願的試了試,出了不少問題,最後放棄了用select組件來作。java
後邊使用select也實現了該功能,能夠查看我下一篇隨筆: https://www.cnblogs.com/mayiaction/p/12066923.htmljquery
後邊發現 auto-complete 組件很簡潔,在其基礎上作了一些改動,最終完成了這個要求,因爲考慮到了模糊查詢的功能,因爲作法的限制,拋棄了iview該組件自帶的模糊搜索,因此代碼複雜了點。ios
代碼以下:數組
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <link rel="stylesheet" type="text/css" href="http://unpkg.com/iview/dist/styles/iview.css"> <script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script> <script type="text/javascript" src="http://unpkg.com/iview/dist/iview.min.js"></script> <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script> <style type="text/css"> #app{padding: 32px;} [myfocus]{ color: #2d8cf0; background: #f3f3f3; } </style> </head> <body> <div id="app"> <auto-complete ref = "test" v-model="nowLabel" @on-change="changeSel" @on-select="selectSel" style="width:200px" icon="ios-arrow-down" > <i-Option v-for="option in selArr" :value="option.label+'|'+option.value" :key="option.value" > <span >{{option.label}}</span> </i-Option> </auto-complete> </div> </body> <script type="text/javascript"> window.vm = new Vue({ el: '#app', data: { nowLabel: '', //存儲輸入框中顯示的內容 nowSel: undefined, //存儲須要提交給後臺的value lastLabel: '', //存儲上一次輸入的內容 selArr:[], //存儲select下拉框綁定的列表 isSel:false, ////因爲選中和輸入內容都會觸發onchange,設置此變量進行區分兩種狀況 //存儲頁面的原始列表 prevArr:[ { value:'n', label:'NewYork' }, { value:'l', label:'London' }, { value:'s', label:'Sydney' }, { value:'o', label:'Ottawa' }, { value:'p', label:'Paris' }, { value: 'c', label: 'Canberra' } ] }, created:function(){ this.selArr = this.prevArr; //頁面初次加載,下拉列表就是原始列表 }, methods: { filterMethod:function(value,arr) { var newArr = []; for(var i=0;i<arr.length;i++){ if(arr[i].label.toUpperCase().indexOf(value.toUpperCase()) !== -1){ //模糊查詢到了,塞入新數組 newArr.push(arr[i]); } } this.selArr = newArr; }, changeSel:function(){ //更改事件 var that = this; if(that.isSel){ //若是輸入框的改變是選中內容引起的,就什麼也不作,同時從新初始化標識,爲了解決選中同一內容兩次引起的bug that.isSel = false; return false; } var input = that.nowLabel; //獲取輸入框輸入的內容 that.nowSel = input; that.clearSelCss(that,"test"); //將輸入內容與上一次的輸入內容比對上一次輸入內容,判斷是到初始化列表中查仍是從上次查詢結果列表查 if(input == null || input == undefined || input == ""){ //輸入內容是空,顯示原始列表 that.selArr = that.prevArr; }else if(input.indexOf(that.lastLabel)==0){ //這次輸入內容是上次輸入內容的開頭,不須要到原始列表查,只要到上次查詢結果中查 that.filterMethod(input,that.selArr); }else{ //其餘狀況到原始列表中查 that.filterMethod(input,that.prevArr); } this.lastLabel = input; }, selectSel:function(val){ let that = this; //選中事件 that.isSel = true; var label = val.split("|")[0]; that.nowSel = val.split("|")[1]; Vue.nextTick(function () { that.nowLabel = label; that.clearSelCss(that,"test"); var focusItem = $(that.$refs.test.$el).find(".ivu-select-item-focus"); //定義一個屬性,用於給選中項設置樣式,之因此不設置class,是由於iview會將class替換掉 focusItem.attr("myfocus","myfocus"); }); }, clearSelCss:function(that,ref){ //清除掉已經被選中的項的css var lastSel = $(that.$refs[ref].$el).find("[myfocus]"); lastSel.removeAttr("myfocus"); } } }) </script> </html>
效果以下,當選中了列表中的內容的時候,須要提交給後臺的是選中項的value,而不是labelapp
當本身輸入內容的時候,因爲並不肯定value的值,就認爲輸入框中的內容就是value,效果以下:iview
若是有什麼疑問,歡迎留言!