• vue-music 关于Search(搜索页面)-- 搜索历史


    搜索历史展示每一次搜索过,并选中的关键字,保存数据到数组。搜索历史数据是需要在多个组件中共享的,所以保存在vuex 中 searchHistory 数组中,保存触发在搜索列表点击选中之后派发事件到search.vue 中,search.vue 监听事件并提交actions改变共享数组,改变vuex 中共享数据之前需要存到本地缓存 Localstorage 中,在本地存储 中判断如果当期历史搜索数据在数据中已经有则提前插入到第一位,没有则添加到数组中存储

    在common 中 创建cache.js 里面写所有相关存储的逻辑代码。使用goog-storage 库 方便调用localstorage 相关api

    保存本地搜索历史首先获取访问本地存储中的key 如果已经有值则赋值,没有则赋值为空数组,插入新数据前先与当前历史数据列表比较有没有相同数据,有则且在第一个位置原样返回该数据,有且大于第一个位置则删除该数据,然后再插入,并且插入大于最大限制条数的时候,删除数组的最后一个元素。最后调用storage.set(key,val) 存到本地缓存中。并且 在action 中提交到vuex数据中

    cache.js

    import storage from 'good-storage'
    
    const SEARCH_KEY = '__search__'
    const SEARCH_MAX_LEN = 15
    
    // 检索函数,判断新增的是否存在
    function insertArray(arr, val, compare, maxLen) {
      const index = arr.findIndex(compare)
      if (index === 0) {
        return
      }
      if (index > 0) {
        arr.splice(index, 1)
      }
      arr.unshift(val)
      if (maxLen && arr.length > maxLen) {
        arr.pop()
      }
    }
    
    export function saveSearch(query) {
      let searches = storage.get(SEARCH_KEY, [])
      insertArray(searches, query, (item) => {
        return item === query
      }, SEARCH_MAX_LEN)
      storage.set(SEARCH_KEY, searches)
      return searches
    }

      export function loadSearch() {
        return storage.get(SEARCH_KEY, [])
      }

     

    actions.js

    export const saveSearchHistory = function({commit},query){
      commit(types.SET_SEARCH_HISTORY,saveSearch(query));
    } 

    state.js



    import {loadSearch} from 'common/js/cache.js'; const state = { singer:{}, playing:false, fullScreen:false, playList:[], sequenceList:[], mode:playMode.sequence, currentIndex:-1, disc:{}, topList:{}, searchHistory:loadSearch()    //默认值从本地存储中获取 } export default state

    将获取来的vuex数据遍历到历史数据列表组件上search-list 组件

    <template>
      <div class="search-list" v-show="searches.length">
        <ul>
          <li :key="item" class="search-item" @click="selectItem(item)" v-for="item in searches">
            <span class="text">{{item}}</span>
            <span class="icon" @click.stop="deleteOne(item)">
              <i class="icon-delete"></i>
            </span>
          </li>
        </ul>
      </div>
    </template>
    
    <script type="text/ecmascript-6">
      export default {
        props: {
          searches: {
            type: Array,
            default: []
          }
        },
        methods: {
          selectItem(item) {
            this.$emit('select', item)
          },
          deleteOne(item) {
            this.$emit('delete', item)
          }
        }
      }
    </script>

    组件上派发一个选中本条历史数据和删除本条历史数据的方法,选中本条可以引用addQuery 方法将本条数据再次填在input 搜索框中。删除本条调用action 方法

    function deleteFromArray(arr, compare) {
      const index = arr.findIndex(compare)
      if (index > -1) {
        arr.splice(index, 1)
      }
    }
    
    // 删除后的数组存到本地
    export function deleteSearch(query) {
      let searches = storage.get(SEARCH_KEY, [])
      deleteFromArray(searches, (item) => {
        return item === query
      })
      storage.set(SEARCH_KEY, searches)
      return searches
    }
    
    ------------------ actions.js -----
    
    export const deleteSearchHistory = function({commit},query){
      commit(types.SET_SEARCH_HISTORY,deleteSearch(query));
    } 

    点击清除所有历史数据方法和删除本条的逻辑一样,需要提交actions 清除本地缓存数据,并返回一个空数组赋值给vuex 数据,然后组件通过mapActions 调用该方法清空历史数据

    // 清除数据
    export function clearSearch() {
      storage.remove(SEARCH_KEY)
      return []
    }
    
    // 提交空数组
    export const clearSearchHistory = function({commit}){
      commit(types.SET_SEARCH_HISTORY,clearSearch());
    }

    search.vue 引入mapActions ,代理调用clearSearchHistory 方法

    import {mapActions,mapGetters} from 'vuex'
    
    ...mapActions([
      'saveSearchHistory',
      'deleteSearchHistory',
      'clearSearchHistory'
    ])
    
    // 绑定派发事件   
    deleteAll(){
      this.clearSearchHistory();
    },
    
    //!注意这里可以直接将代理的方法直接绑定到监听事件中,可省略再次写方法名
    
    // 之前是
    <span class="clear" @click="deleteAll">
    
    // 可改为
    <span class="clear" @click="clearSearchHistory">

    优化体验,点击清空所以数据的时候弹窗确认删除才删除

    建立confirm 组件,向外派发点击确认按钮时的事件,这里就直接把确认的派发事件写成 clearSearchHistory 。取消的话影藏自身就行

    // confirm 组件
    <template> <transition name="confirm-fade"> <div class="confirm" v-show="showFlag" @click.stop> <div class="confirm-wrapper"> <div class="confirm-content"> <p class="text">{{text}}</p> <div class="operate"> <div @click="cancel" class="operate-btn left">{{cancelBtnText}}</div> <div @click="confirm" class="operate-btn">{{confirmBtnText}}</div> </div> </div> </div> </div> </transition> </template> <script type="text/ecmascript-6"> export default { props: { text: { type: String, default: '' }, confirmBtnText: { type: String, default: '确定' }, cancelBtnText: { type: String, default: '取消' } }, data() { return { showFlag: false    // 内部变量控制其显示影藏 } }, methods: { show() { this.showFlag = true }, hide() { this.showFlag = false }, cancel() { this.hide() this.$emit('cancel') }, confirm() { this.hide() this.$emit('confirm') } } } </script>
  • 相关阅读:
    app已损坏,打不开。你应该将它移到废纸篓。
    Mac/win eclipse genymotion 插件下载地址
    过大年
    error: L6235E: More than one section matches selector
    android socket 线程连接openwrt与arduino单片机串口双向通信
    PCB对应封装元件名称
    网页代码总结
    sql一个表中的数据插入到另外一个表中
    树莓派更换镜像源
    SQL 中的 AND OR
  • 原文地址:https://www.cnblogs.com/inzaghihao/p/7930472.html
Copyright © 2020-2023  润新知