vue項目搜索歷史功能的實現


播放器項目中歌曲搜素頁面的

首先需要在state定義搜索歷史,在其中保存搜索歷史

state.js:
// 搜索歷史: searchHistory: []

 mutations中新增改變搜索歷史的方法

mutations.js:
SET_SEARCH_HISTORY(state, history) { state.searchHistory = history }  

在actions中需要提交一個狀態改變history,由於需要存儲到vuex中

export const saveSearchHistory = function ({
  commit
}, query) {
  commit('SET_SEARCH_HISTORY', saveSearch(query))
}  

在utils中新建一個cache.js,用來存儲localstroage.js,首先安裝good-stroage作為存儲緩存的依賴

cache.js:
import storage from 'good-storage';
定義一個key代表存儲搜索歷史:
const SEARCH_KEY = "__search__"
// 只緩存十五條數據
const SEARCH_MAX_LEN = 15

 實現邏輯:

// arr總數組,val插入的數組,maxlen總條數
function insertArray(arr, val, maxLen) {
  const index = _findIndex(arr, val);
  // 如果搜到第一條數據返回即可
  if (index === 0) {
    return
  }
  // 如果數組中有這條數據,還不是在最前面,則刪除之前的數據
  if (index > 0) {
    arr.splice(index, 1);
    console.log('刪除已存在的數據')
  }
  // 把當前的插入最前面
  arr.unshift(val)
  // 當存儲的長度大於設置的長度則移除最后一條:
  if (maxLen && arr.length > maxLen) {
    arr.pop()
  }
}
export function saveSearch(query) {
  // 獲取當前,如果沒有存過則是空數組:
  let searches = storage.get(SEARCH_KEY, [])
  insertArray(searches, query, SEARCH_MAX_LEN);
  storage.set(SEARCH_KEY, searches);
  return searches
}

// 遍歷數組對象,找到插入值的索引(這個方法其實不太好,其實就是把對象轉換成字符串后向后不斷對比,應該根據id來判斷是否一致)
function _findIndex(l, o) {
  var objStr = JSON.stringify(o)
  return l.reduce((index, ele, i) => {
    if (JSON.stringify(ele) === objStr) {
      return i
    } else {
      return index
    }
  }, -1)
}

在搜素結果的組件中,給每一項添加一個點擊事件,傳遞值,並讓父組件監聽:

  selectItem(item) {
      this.$emit("select", item);
   },

父組件中監聽,並使用mapActions提交變化

  methods: {
    async _getSearchHot() {
      const { data: res } = await getSearchHot();
      this.hotSearchList = res.slice(0, 8);
      console.log(this.hotSearchList);
    },
    ...mapActions(["saveSearchHistory"]),
    onSaveSearch(item) {
      this.saveSearchHistory(item);
    }
  }

 在瀏覽器中測試,分別輸入一首海闊天空和光輝歲月,可以看到前一步提交和后一步提交的狀態

 

 

 

 

 這時候再搜索第一次搜索的海闊天空,會把之前的刪除,並新增一條海闊天空插入到數組最前面

 

 在瀏覽器的控制台中的Application也可以查看到localstroage的變化

接下來就是定義一個基礎組件,把所有歷史記錄使用mapGetters獲取,並循環遍歷

<template>
  <div class="search-list" v-show="searches.length">
    <ul>
      <li v-for="(item,index) in searches" :key="index" >
        {{item.name}}
        <i class="iconfont icondel" ></i>
      </li>
    </ul>
  </div>
</template>

  到此頁面也渲染完成了

 

 

 

 接下來實現點擊播放歷史記錄中的歌曲,和刪除歷史記錄中的歌曲,因為是基礎組件,所以向外暴露出事件讓父組件監聽

      <li v-for="(item,index) in searches" :key="index" @click="selectItem(item)">
        {{item.name}}
        <i class="iconfont icondel" @click.stop="deleteTag(item)"></i>
      </li>

 

  methods: {
    selectItem(item) {
      this.$emit("select", item);
    },
    deleteTag(item) {
      this.$emit("delete", item);
    }
  }

父組件中監聽

<search-list :searches="searchHistory" @select="selectItem" @delete="deleteSearch"></search-list>

播放點擊的歌曲很簡單,使用之前定義的mapactions中的insertSong即可,之前歌曲的數據也都一一傳入

   selectItem(item) {
      this.insertSong(item);
    },

 刪除播放的歷史記錄中的歌曲,需要 定義一個新的actions,把之前的history重新刪掉選中項后再返回結果

export const deleteSearchHistory = function ({
  commit
}, query) {
  commit('SET_SEARCH_HISTORY', deleteSearch(query))
}

 在cache.js中新增方法

// 從數組刪除方法:
function deleteFromArray(arr, val) {
  const index = _findIndex(arr, val);
  if (index > -1) {
    arr.splice(index, 1)
  }
}

// 刪除搜索歷史的某一項:
export function deleteSearch(query) {
  let searches = storage.get(SEARCH_KEY, []);
  deleteFromArray(searches, query);
  // 刪除完再保存數組:
  storage.set(SEARCH_KEY, searches);
  // 同時返回被刪除的數組
  return searches
}

最后在父組件中定義子組件的刪除事件中調用actions並傳入item即可

   deleteSearch(item) {
      this.deleteSearchHistory(item);
    }

點擊后測試效果,可以發現已經成功了

 

 

 

 最后實現點擊垃圾清空全部歷史記錄的功能,這個就很簡單了

一樣的方法定義一個actions

// 點擊垃圾桶,刪除全部歷史記錄
export const clearSearchHistory = function ({
  commit
}) {
  commit('SET_SEARCH_HISTORY', clearSearch())
}

cache.js新增一個清除全部的函數

export function clearSearch() {
  storage.remove(SEARCH_KEY)
  return []
}

 點擊時候調用即可,在這里用了vant的dialog組件

    deleteAllHis() {
      Dialog.confirm({
        message: "是否清空歷史記錄?",
        className: "dialog_themedark",
        confirmButtonText: "清空",
        width: "250px"
        // transition: "zoomIn"
      }).then(() => {
        this.clearSearchHistory();
      });
    }

 效果

 

 點擊后全部清空

到此,搜索歷史的功能也就做完了 

  

 

  

 

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM