文章目录
- 功能实现
- 1.点击搜索框,显示列表,点击其它地方搜索列表消失.
- 2.按下enter键,也可以进行搜索
- 3.点击搜索框不输入搜索内容,显示热门搜索和历史搜索。点击搜索框输入搜索内容,直接显示搜索列表
- 4.将历史搜索内容存储到LocalStorage.
- 5.删除历史记录
- 搜索框组件源码
功能实现
1.点击搜索框,显示列表,点击其它地方搜索列表消失.
在input组件上监听focus与blur事件,设置isFoucus标志量,通过v-if控制搜索列表是否显示,在computed中进行计算。
<el-input @focus="focus" @blur="blur" />
<el-card v-if="isSearch" >...</el-card>
computed: {
isSearch() {
return this.isFocus;
}
}
2.按下enter键,也可以进行搜索
在input组件上监听enter事件(注意在组件上使用原生的方法需要使用native关键字)
<el-input @keyup.enter.native="searchHandler"/>
3.点击搜索框不输入搜索内容,显示热门搜索和历史搜索。点击搜索框输入搜索内容,直接显示搜索列表
显示列表时通过v-if进行控制时候显示,在computed中进行判断是应该显示热门搜索和历史搜索还是直接显示搜索列表
<dl v-if="isHistorySearch">...</dl>
<dl v-if="isSearchList">...</dl>
computed: {
isHistorySearch() {
return this.isFocus && !this.search; //获取了焦点并且搜索框内容为空显示热门搜索和历史搜索
},
isSearchList() {
return this.isFocus && this.search; //获取了焦点并且搜索框内容不为空直接显示搜索列表
},
}
4.将历史搜索内容存储到LocalStorage.
因为LocalStorage只能以String的形式存在,所以要存的是否要转为String类型,取得是否再转为json,为了方便,可以建立一个通用的store.js
const LOCAL_STORAGE_KEY = "searchHistory";
class Store { }
//通过Store.xxx写法可以把xxx实现静态方法的效果,无需创建Store的实例即可使用
//将[]存入localStorage
Store.saveHistory = (arr) => {
localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(arr));
}
//从localSotrage取出
Store.loadHistory = () =>JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY))
//清空全部localStorage历史查询
Store.removeAllHistory=()=>{localStorage.removeItem(LOCAL_STORAGE_KEY)}
module.exports = Store
同时我们通过element-ui 的<el-tag>
组件,为搜索历史记录提供了好看的样式。而生成的搜索历史样式是随机生成的,可以看见我们之前存入LocalStorage的搜索记录中还存入了对应的tag式样。
types: ["", "success", "info", "warning", "danger"] //搜索历史tag式样
生成[min,max)区间随机数
class RandomUtil {
}
//静态方法,获得随机数
RandomUtil.getRandomNumber = (min, max) => parseInt(Math.random() * (max - min)) + min
module.exports = RandomUtil
同时在存入LocalStorage之前要判断该搜索记录已经存在了,如果存在,则不存入.
如果没有任何搜索记录,将history字段设为false,只显示热门搜索不显示历史搜索
searchHandler() {
//随机生成搜索历史tag式样
let n = RandomUtil.getRandomNumber(0, 5);
let exist =
this.historySearchList.filter(value => {
return value.name == this.search;
}).length == 0
? false
: true; //判断搜索是否已经存在了
if (!exist) {
this.historySearchList.push({ name: this.search, type: this.types[n] });
Store.saveHistory(this.historySearchList);
}
//如果没有搜索记录,history字段为false,只显示热门搜索不显示历史搜索
this.history = this.historySearchList.length == 0 ? false : true;
},
5.删除历史记录
处理element-ui tag组件的@close事件,删除掉historySearchList中对应的value,重新存入LocalStorage.同时如果历史记录数为0了,将history字段置为false,使得不显示历史记录。
<el-tag
v-for="search in historySearchList"
:key="search.id"
closable
:type="search.type"
@close="closeHandler(search)">
</el-tag>
closeHandler(search) {
this.historySearchList.splice(this.historySearchList.indexOf(search), 1);
Store.saveHistory(this.historySearchList);
if (this.historySearchList.length == 0) {//历史记录数为0了,将history字段置为false,使得不显示历史记录。
this.history = false;
}
}
👿但是你会发现这样的话,虽然一条历史记录被删除了,但是每次删除后搜索记录列表就不显示了。
聪明的同学已经想到原因了:点击搜索记录列表内的内容,触发了搜索input输入框的blur事件
解决的方法也很简单:在blur事件中,重置focus焦点时设置timeout,而删除历史记录后,取消掉这个timeout,不重置focus焦点.
blur() {
var self = this;
this.searchBoxTimeout = setTimeout(function() {
self.isFocus = false;
}, 300);
},
closeHandler(search) {
this.historySearchList.splice(this.historySearchList.indexOf(search), 1);
Store.saveHistory(this.historySearchList);
//取消timeout
clearTimeout(this.searchBoxTimeout);
if (this.historySearchList.length == 0) {
this.history = false;
}
},
搜索框组件源码