1. 程式人生 > >vue實現輸入框的模糊查詢(節流函式的應用場景)

vue實現輸入框的模糊查詢(節流函式的應用場景)

  上一篇講到了javascript的節流函式和防抖函式,那麼我們在實際場合中該如何運用呢?

  首先,我們來理解一下:節流函式首先是節流,就是節約流量、記憶體的損耗,旨在提升效能,在高頻率頻發的事件中才會用到,比如:onresize,onmousemove,onscroll,oninput等事件中會用到節流函式;

  輸入框的模糊查詢功能原理分析

    所謂模糊查詢就是不需要使用者完整的輸入或者說全部輸入資訊即可提供查詢服務,也就是使用者可以在邊輸入的同時邊看到提示的資訊(其實是查詢出來匹配到的資訊),百度的搜尋功能就是很好的模糊查詢的例子;其實模糊查詢的原理就是給輸入框繫結oninput事件監聽使用者輸入情況,然後每次使用者只要在輸入框中輸入了資訊就觸發事件進行查詢然後實時展示;原理很簡單,但是實現起來會有一些問題,我們可以想想,每輸入一個字元都會觸發事件,那如果我們需要輸入很長的資訊呢,那查詢是不是就得觸發多次?ajax連續多次觸發,再加上如果我們的方法體中有操作DOM元素的方法,那麼必然會給我們的瀏覽器進入假死甚至崩潰狀態;那麼我們有沒有辦法來解決此類問題呢?答案是:有的;(不瞭解模糊查詢功能的同學可以出門右轉去百度首頁試一下搜尋,給你5分鐘,我等你回來)

 

  HTML檢視層程式碼:

        <div id="app">
        //輸入框,繫結輸入框的值是變數input_value的值,然後對輸入框做了事件繫結keyup,在使用者輸入的時候會觸發 <input type="text" placehold="請輸入id進行查詢" v-model="input_value" @keyup="throttle" ref="input"/> <ul v-show="state"> <li v-for="(item,index) in list" :key="index" > <span>{{item.id}}</span> <span>{{item.name}}</span> <span>{{item.time}}</span> </li> </ul> </div>

  從上述程式碼中我們可以很明顯的看到DOM結構,就是一個輸入框,我們給輸入框加了ref屬性是為了方便我們後面操作DOM拿到輸入框的值(詳情可見ref和$refs的區別博文https://www.cnblogs.com/dengyao-blogs/p/11350292.html),然後下面有一個ul列表,不過ul列表是判斷展示的;(至於為什麼會用v-show而不是v-if,可以點選連結查閱之前的博文  https://www.cnblogs.com/dengyao-blogs/p/11378228.html);

 

  js資料邏輯層程式碼:

  

    // 例項化 vue物件
        new Vue({
            el:"#app",
            data:{
                input_value:"",
                state:false,
                statu:true,
                dataList:[
                { id: "1001", name: "哈哈", time: "20170207" },
                { id: "1002", name: "呵呵", time: "20170213" },
                { id: "1103", name: "曉麗", time: "20170304" },    
                { id: "1104", name: "小蘭", time: "20170112" },
                { id: "1205", name: "財務", time: "20170203" },
                { id: "1206", name: "嘻嘻", time: "20170208" },
                { id: "1307", name: "測試", time: "20170201" }
              ],    
                  list:[]
        },
        
        methods:{//觸發keyup事件之後觸發的方法
            search(){

      //這個變數主要是用來測試節流後和不節流的區別
          var i=0;
          console.log(i++);

//定義的新陣列存放篩選之後的資料
                this.list=[];
                //拿到當前input輸入框輸入的值
                this.input_value=this.$refs.input.value;
                //判斷展示ul列表,如果輸入了就展示沒輸入就不展示
                if(this.input_value.length>0){
                    this.state=true;
                }else{
                    this.state=false;
                }
                
                //迴圈模擬資料的陣列
                this.dataList.map((msg)=>{
                    //拿當前json的id、name、time去分別跟輸入的值進行比較
                    //indexOf 如果在檢索的字串中沒有出現要找的值是會返回-1的,所以我們這裡不等於-1就是假設輸入框的值在當前json裡面找到的情況
                    if(msg.id.indexOf(this.input_value)!=-1    || msg.name.indexOf(this.input_value)!=-1 ||  msg.time.indexOf(this.input_value)!=-1){
                        //然後把當前json新增到list陣列中
                        this.list.push(msg);
                    }
                })
            },
        }
    })

 

 

 

 

   js資料邏輯層程式碼其實不難,主要就是給input綁定了keyup事件,在使用者輸入的時候會觸發search事件,使用者每輸入一個字元都會觸發一次;然後我們通過this.$refs.input.value來獲取輸入框當前的值並賦值給變數this.input_value,然後我們對this.input_value的長度進行判斷來實現對使用者是否輸入的判斷,如果用書輸入了我們就把v-show繫結的值state賦值給true,反之則賦值為false;然後我們來用ES6的map方法來迴圈我們的dataList陣列,dataList陣列的資料是模擬後臺介面資料,通過indexOf方法是否等於-1來進行判斷當前json裡面是否有輸入框中輸入的陣列,indexOf是javascript提供的操作字串方法,呼叫方式:string.indexOf("要查詢的值"),如果str中沒有要查詢的值會返回我們-1,如果有會直接返回給我們查詢資料的當前下標;所以我們可以藉助indexOf是否等於-1來進行判斷當前json中是否有我們要查詢的字串;如果有的話,我們只需要把當前json新增到空陣列list中即可,然後li繫結list展示;

 

  效果圖如下:

  

 

 

   到這裡我們就可以看到我們要的模糊查詢功能已經實現了,但是我們上面講到模糊查詢會影響瀏覽器的效能,從控制檯輸入的變數i的值可以看到我們的search方法已經被呼叫了8次,我們輸入的字元越長被呼叫的次數越多,如果方法裡面有操作DOM的行為效能影響會更嚴重;所以我們現在來加上節流函式來看看:

  

              //節流函式
            throttle(){
                //保持this的指向始終指向vue例項
                var that=this;
                if(!that.statu){
                    return;
                }    
                that.statu=false;
                setTimeout(function(){
                    console.log(new Date());
                    that.search();
                    that.statu=true;
                },1000)
            },

    我們把我們寫的節流函式封裝在throttle裡面執行,把@keyup繫結的點選事件修改為throttle,當用戶輸入字元的時候觸發節流函式;效果圖如下:

  

  

 

 

   我們可以從控制檯很清晰的看到當我們使用節流函式的時候,當我們輸入了8個字元我們的方法只執行了兩次,並且執行時間是每隔一秒執行一次,一個方法執行2次肯定會比執行8次不管是在效率還是在效能方面都會是比較大的提升,用了節流函式之後相對上面沒用的節流函式來說,我們極大的實現了效能提升、優化,所以在高頻率觸發的事件中我們是可以建議用節流函式來進行控制和解決問題的;

&n