基於Vue實現關鍵詞實時搜索高亮顯示關鍵詞

最近在作移動real-time-search於實時搜索和關鍵詞高亮顯示的功能,經過博客的方式總結一下,同時但願可以幫助到別人~~~html

若是不喜歡看文字的朋友我寫了一個demo方便已經上傳到了github上,能夠clone下來直接看代碼 https://github.com/IT0315/rea...
下面是demo運行的效果圖
圖片描述vue

好了閒話很少說直接上代碼ios

實時搜索

實時搜索經過觸發input事件和定時器來實現git

<input v-model="keyWords" type="text" placeholder="請輸入關鍵詞" @input="handleQuery">

在每次輸入框的值變化的時候都會執行handleQuery方法github

clearTimer () {
      if (this.timer) {
        clearTimeout(this.timer)
      }
    },
    handleQuery (event) {
      this.clearTimer()
      console.log(event.timeStamp)
      this.timer = setTimeout(() => {
        console.log(event.timeStamp)
        // console.log(this.lastTime)
        // if (this.lastTime - event.timeStamp === 0) {
        this.$http.post('/api/vehicle').then(res => {
          console.log(res.data.data)
          this.changeColor(res.data.data)
        })
        // }
      }, 2000)
    },

在handleQuery方法中有一個定時器,經過設置時間來控制搜索的執行,因爲輸入時input的框中的值老是變化的,因此每次變化都會執行一次handleQuery,咱們經過clearTimer方法清除timer定時器,若是兩次輸入的間隔時間小於你設置的時間間隔(2s)的話第一個按期器將會被清除,同時執行第二個定時器。這樣就實現了實施搜多的控制,而不是每次輸入的時候就去請求數據。axios

注意:若是時間設置太短或者說咱們服務器請求較慢的話,可能第一次查詢尚未返回便進行了第二次查詢,那麼返回的數據將是兩次查詢的結果,形成查詢結果的混亂,若是使用的是axios能夠利用axios.CancelToken來終止上一次的異步請求,防止舊關鍵字查詢覆蓋新輸入的關鍵字查詢結果。api

高亮顯示

經過RegExp實現對關鍵詞的替換,經過添加class實現關鍵詞高亮顯示服務器

changeColor (resultsList) {
      resultsList.map((item, index) => {
        // console.log('item', item)
        if (this.keyWords && this.keyWords.length > 0) {
          // 匹配關鍵字正則
          let replaceReg = new RegExp(this.keyWords, 'g')
          // 高亮替換v-html值
          let replaceString =
            '<span class="search-text">' + this.keyWords + '</span>'
          resultsList[index].name = item.name.replace(
            replaceReg,
            replaceString
          )
        }
      })
      this.results = []
      this.results = resultsList
}

在查詢到結果後執行changeColor方法將查詢出來的數據傳遞過來經過RegExp來將關鍵詞替換成huml標籤,同時用vue中的v-html進行綁定。最後將demo完整的代碼展現出來異步

<template>
  <div class="Home">
   <input v-model="keyWords" type="text" placeholder="請輸入關鍵詞"  @input="handleQuery">
   <ul>
       <li v-for="(item,index) in results" :key='index' v-html='item.name'></li>
   </ul>
  </div>
</template>

<script>
export default {
  name: 'Home',
  data () {
    return {
      keyWords: '',
      results: []
    }
  },
  methods: {
    clearTimer () {
      if (this.timer) {
        clearTimeout(this.timer)
      }
    },
    handleQuery (event) {
      this.clearTimer()
      console.log(event.timeStamp)
      this.timer = setTimeout(() => {
        console.log(event.timeStamp)
        // console.log(this.lastTime)
        // if (this.lastTime - event.timeStamp === 0) {
        this.$http.post('/api/vehicle').then(res => {
          console.log(res.data.data)
          this.changeColor(res.data.data)
        })
        // }
      }, 2000)
    },

    changeColor (resultsList) {
      resultsList.map((item, index) => {
        // console.log('item', item)
        if (this.keyWords && this.keyWords.length > 0) {
          // 匹配關鍵字正則
          let replaceReg = new RegExp(this.keyWords, 'g')
          // 高亮替換v-html值
          let replaceString =
            '<span class="search-text">' + this.keyWords + '</span>'
          resultsList[index].name = item.name.replace(
            replaceReg,
            replaceString
          )
        }
      })
      this.results = []
      this.results = resultsList
    }
  }
}
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.search-text{
color: red;
}
</style>

最後,若是本文對你的學習或者工做有幫助的話,麻煩給個star鼓勵下啦~~~post

相關文章
相關標籤/搜索