uniapp(vue3+ts)历史搜索记录

400 阅读1分钟

man-black-and-white-board-vintage-old-portrait-657759-pxhere.com.jpg

历史记录

class Cache<T> {
  key: string // 本地存储的key
  storage: T[] // 本地存储的历史记录数据
  maxLength: number // 存储历史记录的条数
  constructor(key: string, maxLength: number = 10) { // 初始化数据
    this.key = key
    this.maxLength = maxLength
    this.get()
  }
  // 获取缓存
  get() {
    const arr = lo(this.key)
    return (this.storage = Array.isArray(arr) ? arr : [])
  }
  // 设置缓存
  set(val: T[]) {
    this.storage = val
    uni.setStorageSync(this.key, val)
  }
  // 删除缓存
  remove() {
    this.storage = []
    uni.removeStorageSync(this.key) // 删除存储的key
  }
  // 删除一个
  delete(index: number) {
    this.storage.splice(index, 1) // 点击某一项时删除
    this.set(this.storage) // 重新存储
  }
  // 存储maxLength个
  save(key: T) {
    const { storage: his = [], maxLength } = this,
      index = his.length
    if (!index) his.unshift(key) // 如果缓存没有数据直接添加
    else {
      // 判断storage中是否已经存在传入的数据
      const flag = !his.some((_) => JSON.stringify(_) === JSON.stringify(key))
      if (index < maxLength) { // 如果storage的长度小于定义的最长值
        if (flag) his.unshift(key) // 并且数组中没有这个值在头部添加
      } else { // 大于定义的长度
        if (flag) { // 并且数组中没有传入的这个值
          his.pop() // 删除最后一项
          his.unshift(key) // 头部添加新值
        }
      }
	}
    this.set(his) // 重新存储
  }
}

export default Cache

使用

image.png

<template>
  <div class="h86vh" overflow-y-auto overflow-x-hidden>
    <div bg="#F8F8F8" p="x-24rpx y-16rpx" text-28 between relative>
      <input
        flex-1
        bg-white
        b-rd-36rpx
        p="t16rpx r16rpx b14rpx l68rpx"
        v-model="keyword"
        placeholder-style="color:#ccc"
        placeholder="请输入要查询的内容"
        @confirm="search"
      />
      <i i-ri-search-line text="#999 32" absolute left-48 />
      <span ml24rpx text="#ccc" @click="cancel">取消</span>
    </div>
    <div p24rpx text="#666 24">
      <div between text-30>
        <span>历史搜索</span>
        <span i-octicon-trash-24 @click="show = true" />
      </div>
      <div flex items-center flex-wrap>
        <div
          v-for="(item, index) in history"
          :key="index"
          bg="#F3F3F3"
          b-rd-32
          p="x24rpx y10rpx"
          m="r24rpx t24rpx"
          @click="searchHistory(item)"
        >
          {{ item }}
        </div>
      </div>
    </div>
  </div>
  <Modal
    :show="show"
    content="是否删除所有历史记录?"
    cancelText="取消"
    confirmText="确定"
    @cancel="show = false"
    @confirm="remove"
  />
</template>

<script lang="ts" setup>
import { ref, computed } from 'vue'
import Cache from '@/utils/cache'

// 定义emits事件
const emits = defineEmits(['confirm'])

// data
const cache = ref(new Cache<string>('SEARCH_HISTORY')), // 实例化工具类
  keyword = ref(''), // 搜索值
  show = ref(false), // 是否显示模态框
  history = computed(() => cache.value.storage) // 通过计算属性取得实例中的缓存数组

// 保存一条历史记录
const searchHistory = (item: string) => {
  keyword.value = item
  search()
}
// 删除缓存
const remove = () => cache.value.remove()

// 保存一条历史记录
const search = () => cache.value.save(keyword.value)
</script>