1、出现历史记录的需求
前些天,项目的啄木鸟计划中提出这样一个问题,每次用户输入什么,应该有历史记录供选择,搜索框获取焦点后会展示搜索历史,搜索历史记录可以存储在前端,由浏览器存储记录,这里就要提到我们常见的localStorage和sessionStorage了。
可以先打开浏览器的检查—Application检查存储的数据(当然这是已经实现好了的存储),也就是说我每次查询时都将我的输入存到localstorage中,下次获取到改输入框的焦点时将所有数据源展示出来。当然,思想很简单,但实施起来还是出了一些问题。
2、过程中的问题
下面记录我出现一些问题:
1、首先这里输入框有多个,每个输入需要单独处理,不要产生关联,即这个输入框的历史记录不会出现在其它输入框中。
2、最后存储的记录要存放在数组前面,第一行展示,符合用户习惯。
3、只存储前10条即可。
4、当在一个输入框focus,再去另一个输入框focus时,前一个输入框的数据源未来得及关闭,出现闪动(展示了下一个输入框的数据源)。
5 、autoComplete组件一旦设置options则会出现你配置的数据,注意这里的数据格式是数组形式,每一项都是对象{label:value}格式,但是我的currentValue只是一个数组,格式不符合配置的条件,必须将其转化为数组中含有对象的形式.(如图),这里考虑用到循环,每一项都处理成对象。
6、去重(去除重复输入的数据)
3、思路和方法、组件
下面记录思路和方法、使用的组件。
该项目是基于react搭建,使用到antd中的autoComplete,使用浏览器存储方案 localStorage(考虑到关闭浏览器再次打开时不会清除缓存)
autoComplete的使用场景:辅助输入
这里autoComplete输入有两个时机,首先获得焦点 onFocus这时候会从浏览器的localStorage中获取缓存数据;
<AutoComplete
value={item.params[key]}
options={options}
onFocus={() => {
onFocus(index, key);
}}
onChange={(e) => {
onChange(e, index, key);
}}
onDropdownVisibleChange={onDropdownVisibleChange}
/>
其次点击查询时存入。
<Button type="primary" onClick={() => onQuery(item.apiKey, index)} >
说一下我这里的场景,我需要使用react将这十条数据展示成图一的那种,也就是10个输入框,通过map渲染,render。那么这里查询时通过window.localStorage.setItem
存入,该方法第一项需要设置每一项独特的命名方式,以便后文不会重叠。
window.localStorage.setItem(`${prefix}${key}`, JSON.stringify(value));
有个问题就是,如果我保存了多次,那么就要将其多次push到一个数组,而localStorage只能保存字符串,这个通过JSON的方法实现转换,JSON.parse和JSON.stringify,他们的作用分别是:当我将json字符串取出来时可用json.parse()转化为对象;当需要将对象转为json格式字符串时json.stringfy().
解决问题5: 我通过getItem得到的数据是第一行的格式,后面需要遍历生成下面的格式,代码如下:
onfocus时获取缓存,r=window.localStorage.getItem(
p
r
e
f
i
x
{prefix}
prefix{key})
,并处理 r = JSON.parse(r)
;
if (currentResult?.length) {
for (let i = 0; i < currentResult.length; i++) {
v.push({ value: currentResult[i] });
}
}
获取到我们想要的数据格式后,为options赋值setOptions(v);
,效果实现!
解决问题2: 用户输入的字符串需要添加到数组头中,这样每次最后输入的值可在记忆的最上面显示,这里用到数组的unshift方法而不是push.
解决去重问题:
const cur = currentvalue.filter((x: string) => {
return x !== rParams;
});
cur.unshift(rParams);//置于顶部
if (cur.slice(0, 10)) {
setCache(cacheKey, cur.slice(0, 10));
}