zoukankan      html  css  js  c++  java
  • 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: "清空",
             "250px"
            // transition: "zoomIn"
          }).then(() => {
            this.clearSearchHistory();
          });
        }
    

     效果

     点击后全部清空

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

      

      

     

     

      

  • 相关阅读:
    Mysql常用语句
    Java基础知识总结
    ExtJS4.2学习(三)——入门基础
    ExtJS4.2学习(二)——入门基础
    ExtJS 4.2学习(一)——环境搭建
    大三下半学期“饭店餐饮系统”项目笔记
    GUI练习——列出指定目录内容
    Collections之sort的两个方法(自然排序和自定义比较器排序)
    Java集合总结
    访问数据库
  • 原文地址:https://www.cnblogs.com/rmty/p/13064673.html
Copyright © 2011-2022 走看看