移动端使用vux+good-storage实现搜索历史

项目中遇到了要求搞个根据输入内容实时显示搜索列表并且要求做个搜索历史,如下图

这里写图片描述

因为我项目中UI框架用的是vux,而vux正好有个search组件满足UI效果和一些交互逻辑,但是搜索历史还是要自己搞的。

思路是在点击搜索列表的某一项时,将数据推入缓存中,在输入框为空并失焦的状态下,取缓存中是数组数据并显示搜索历史列表。

因为HTML5原生的localStorage api需要将数组转化成字符串进行存储,所以在这里我们使用good-storage来满足我们项目中的需求

1.安装good-storage

npm install good-storage (npm安装)
yarn add good-storage (yarn安装)

2.在公共方法utils文件夹下新建cache.js编写本地存储的方法逻辑
1)得到当前的数据存储情况,将关键字存到数组中
2)缓存到本地的最大数据为15条,将新添加的数据放在第一位
3)如果缓存中已有此数据,则把之前重复的数据删除并将新的关键字存在前面

cache.js

/*
点击搜索结果后把选择的结果保存下来
将方法暴露出去
定义存储搜索的key  _search_定义内部使用的key
*/
import storage from 'good-storage'
const SEARCH_KEY = '_search_'
const SEARCH_MAX_LENGHT = 15

// 插入函数 arr存储的数组 val传入储存的值 compare前后比较的函数 maxlen存入的最大长度
function insertArray (arr, val, compare, maxlen) {
  // 查找要传入的值是否已经在原存储的数据中存在,没有就返回-1
  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.materialCode === query.materialCode
  }, SEARCH_MAX_LENGHT)
  storage.set(SEARCH_KEY, searches)
  return searches
}

index.vue

<template>
    <search
            ref="search"
            :results="result"
            :placeholder="'物料编码/物料描述'"
            v-model="materialModel"
            position="absolute"
            auto-scroll-to-top
            @on-result-click="materialResultClick"
            @on-change="getMaterialResult"
            @on-focus="onFocus"
            @on-cancel="onCancel"
            @on-submit="onSubmit">
            <slot>
              <scroller
                ref="materialList"
                v-model="materialStatus"
                :pullup-config="pullupConfig"
                :scroll-bottom-offset="10"
                :height="scrollHeight"
                use-pullup
                lock-x
                scrollbar-y
                @on-pullup-loading="moreMaterial">
                <div>
                  <div v-if="materialResults.length>0" >
                    <div v-for="(item, index) in materialResults" :key="index" class="history-item border-bottom-line" @click="materialResultClick(item)">
                      <p>物料描述:{{ item.materialDescribe }}</p>
                      <p>物料编码:{{ item.materialCode }}</p>
                      <p>路局物料编码:{{ item.routeMaterialCode }}</p>
                    </div>
                  </div>
                  <p v-else style="height:100%;line-height:200px;text-align:center">查无数据~</p>
                  <div slot="pullup" class="xs-plugin-pullup-container xs-plugin-pullup-down" style="position: absolute; width: 100%; height: 60px; line-height: 60px; bottom: -30px; text-align: center;">
                    <span v-show="materialStatus.pullupStatus === 'default'" />
                    <span v-show="materialStatus.pullupStatus === 'down' || materialStatus.pullupStatus === 'up'" :class="{'rotate': materialStatus.pullupStatus === 'up'}" class="pulldown-arrow"></span>
                    <span v-show="materialStatus.pullupStatus === 'loading'"><spinner type="ios-small"/></span>
                  </div>
                </div>
              </scroller>
            </slot>
          </search>
          <div v-if="historyFlag && searchMaterialList.length>0" class="search-history">
            <div class="title">历史搜索</div>
            <div v-for="(item, index) in searchMaterialList" :key="index" class="history-item border-bottom-line" @click="materialResultClick(item)">
              <p>物料描述:{{ item.materialDescribe }}</p>
              <p>物料编码:{{ item.materialCode }}</p>
              <p>路局物料编码:{{ item.routeMaterialCode }}</p>
            </div>
            <p class="clear-history" @click="clearHistory"><img :src="deleteIcon">清除搜索历史</p>
          </div>
</template>
<script>
activated () {
    let vm = this
    let searches = storage.get('_search_')
    vm.searchMaterialList = searches || []
    if (vm.searchMaterialList.length > 0) {
      vm.historyFlag = true
    } else {
      vm.historyFlag = false
    }
  },
methods: {
 // 点击选择检索到的某项物料
    materialResultClick (item) {
      let vm = this
      saveSearch(item)
      vm.materials = []
      vm.searchMaterialList.push(item)
      storage.set('_search_', vm.searchMaterialList)    
      vm.materialFlag = false
    },
}
</script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值