vue 搜索框添加历史搜索记录

news/2024/7/10 1:20:18 标签: 前端, vue, 搜索框, pinia, vue3

笔者vue项目有一个需求,搜索框添加历史搜索记录。想着很久没更新博客了,记录一下吧。
PS:pinia+vue3+vant+ts,或许你在使用vue2的语法,不要紧,可以根据自己的需求简单改改。

效果图

在这里插入图片描述

正文

搜索框的逻辑就不介绍了,今天这个问题其实是vue操作localStorage。笔者先写了一个工具类来完成对缓存的操作:

export class CacheManager {
  static getHomeSearchHistoryWords() {
    return localStorage.getItem("home-search-history-words")?.split(",") ?? [];
  }

  static setHomeSearchHistoryWords(words: string) {
    return localStorage.setItem("home-search-history-words", words);
  }

  static clearHomeSearchHistoryWords() {
    localStorage.removeItem("home-search-history-words");
  }
}
  • 双问号的作用是左表达式为空或undefined时,会取右表达式的值
  • getHomeSearchHistoryWords 为读取历史搜索记录,返回值为数组;setHomeSearchHistoryWords 为写入,参数为String类型;clearHomeSearchHistoryWords 为清空。

html如下

    <div class="history-words" v-if="words.length">
      <div class="history-words-header">
        <h4>历史搜索</h4>
        <span class="clear" @click="searchStore.clearWords">清空</span>
      </div>
      <Tag
        v-for="item in words"
        style="margin-left: 10px"
        @click="searchStore.onTagClick(item)"
        >{{ item }}</Tag
      >
    </div>
  • Tag 标签是vant中的组件
  • searchStore为pinia定义的状态管理容器
  • words为pinia中的状态,即历史搜索记录

pinia代码如下

export const HomeSearchStore = defineStore("home-search", {
  state: () => ({
    query: "",
    list: [],
    words: [] as string[],
  }),
  actions: {
    search(pushToWords = true) {
	  /**
	  * 这是你的请求,成功后继续执行
	  * do something...
	  */
	  
      if (pushToWords) this.pushWord(this.query);
    },
    onTagClick(item: string) {
      this.query = item;
      this.search(false);
    },
    pushWord(word: string) {
      this.words.unshift(word);
      this.words = Array.from(new Set(this.words)).slice(0, 10);

      CacheManager.setHomeSearchHistoryWords(this.words.join(","));
    },
    setWords(words: string[]) {
      this.words = CacheManager.getHomeSearchHistoryWords();
    },
    clearWords() {
      this.words = [];
      CacheManager.clearHomeSearchHistoryWords();
    },
  },
});
  • 请注意对应html与pinia中函数的调用关系
  • 在其中定义的状态,如 words,在vue2写法就是你data函数返回对象中的一员;其中定义的函数,则在你methods中定义
  • search 函数,你的搜索框发起请求所调用的函数,它的参数 pushToWords(是否存入历史搜索记录)是因为我的需求:点击历史搜索记录或热门标签所发起的请求不会把标签中的内容存入历史搜索记录中(换句话说,只有搜索框中输入内容,然后点击搜索的,才会存入) 而决定的。如果你没有此类需求,可以去掉。
  • onTagClick 如上
  • pushWord 将此次搜索的内容存入words,首先使用 js数组方法 unshift 将 内容存放在words第一位。然后使用Set方法进行数组去重。这样的好处是,发生重复时,会将与以前那一个重复词语删除,会保证顺序性。最后将数组转为字符串存入缓存。
  • setWords 这个函数会在 onMounted 函数中调用,用于在进入页面时,读取缓存中的历史搜索记录
  • clearWords 清空
    到这里其实就完成了。

遇到的问题

笔者刚开始的时候,并不是这样写的。起初没有定义words变量,在html中的所有操作都是直接调用工具类中的函数,也就意味着直接调用缓存的数据。测试时,笔者发现,输入框输入内容后搜索,历史搜索记录正确更新。但是点击清空却没有任何反应,刷新页面才会生效。
为什么一些内容好用,而一些内容不好用呢?在调查过后,找到了原因

  • vue驱动页面更新的是数据,在搜索框输入内容后搜索,笔者所用代码会走网络请求,这个请求在成功时会返回一个数组,我会把这个数组赋值给 list 变量,在页面我使用到 list 来渲染搜索结果的列表。每一次搜索,都会触发数据变化,进而触发页面更新,进而重新调用 getHomeSearchHistoryWords。
  • 而清空操作,没有走网络请求,也就意味着数据没有发生变化,页面也没有更新,于是就没有调用 getHomeSearchHistoryWords。
  • 解决方法就像以上的代码,自己维护一个 words 变量,保证响应式更新。

结束

如果对你有帮助的话,请点一个👍🏻吧~


http://www.niftyadmin.cn/n/1257890.html

相关文章

架构之基本成长解剖

架构演变第一步&#xff1a;物理分离WebServer和数据库 最开始&#xff0c;由于某些想法&#xff0c;于是在互联网上搭建了一个网站&#xff0c;这个时候甚至有可能主机都是租借的&#xff0c;但由于这篇文章我们只关注架构的演变历程&#xff0c;因此就假设这个时候已经是托管…

React Hooks 与 setInterval

笔者在写一个简单的定时器样例时&#xff0c;遇到了一个闭包问题。百度一番后&#xff0c;找到答案。 在此记录一下&#xff0c;该文章非常多的干货。 原文链接

Thinkphp5笔记六:公共模块common的使用

common模块属于公共模块&#xff0c;Thinkphp框架&#xff0c;默认就能调用。 实际用处&#xff1a;任何模块都可能用到的模型、控制、事件提取出来放到公共模块下。 一、公共事件 apps\common\common.php 作用&#xff1a;一般存放密码加密、下拉框封装、读取某文件夹下文件 …

Git报错 Permission to A/BestoneGitHub.git denied to B

今天和同事在弄github的时候&#xff0c;遇到了点小麻烦&#xff0c;在全球最大的中文网上一搜&#xff0c;果然不出所料&#xff0c;找不到写解决方案&#xff0c;于是自己在stackOverFlower上看了好几篇&#xff0c;总结了一下&#xff0c;终于找到解决方案&#xff01;报错如…

利用PHPExcel导出Excel相关设置

功能包括&#xff1a; 1、设置单元格格式&#xff0c;包括单元格边框、单元格高度、单元格宽度 2、合并指定的单元格 3、设置Excel数据源&#xff0c;并将数据源保护起来&#xff08;这个是为了实现单元格下拉选项功能&#xff09; 4、设置字体样式 public function export(){/…

codeforces_346A Alice and Bob(数学)

题目链接:http://codeforces.com/problemset/problem/346/A 参考链接:http://blog.csdn.net/loy_184548/article/details/50174615 感受到数学在博弈论中的强大。 考虑最后终止状态的序列-无法取出任意两个数他们的差值不存在这个序列中:那么这必定是个首项等于公差的等差序列 …

进阶之路(基础篇) - 001 亮一个led灯

1 /*********************************2 代码功能&#xff1a;点亮一个led灯3 使用函数&#xff1a;4 pinMode(引脚号,模式);5 digitalWrite(引脚号,电平状态); //默认低电平(或浮空)6 创作时间&#xff1a;2016*10*077 作者邮箱&#xff1a;jikexianfengoutloo…

实训-利用HTML和CSS制作一个网页界面

目录项目介绍需求分析1.Header&#xff1a;2.Body&#xff1a;3.Footer页面布局及样式实现1.引入CSS文件及初始化2.实现头部&#xff08;1&#xff09;logo&#xff08;2&#xff09;导航栏&#xff08;3&#xff09;中英文切换至此为止&#xff0c;头部完成3.轮播图&#xff0…