Vue项目搜索历史功能(详细)
看效果图:
html代码:
<template>
<div class="qqq">
<!-- 顶部搜索框 -->
<div class="search">
<!-- 返回上一步 -->
<div @click="back">
<img src="../assets/img/left.png" />
</div>
<div>
<input
type="text"
placeholder="请输入内容"
v-model="keywords"
@input="changevalue($event)"
ref="getValue"
/>
</div>
<div @click="quxiao" v-show="show" style="color:grey;">取消</div>
<div @click="search" v-show="!show">搜索</div>
</div>
<!-- 历史搜索 -->
<div class="history" v-show="show">
<p>历史搜索</p>
<p>
<!-- 删除 -->
<img src="../assets/img/delete.png" @click="del" />
</p>
</div>
<!-- 历史搜索列表 -->
<div class="hislist">
<span v-for="(item,index) in hislist" :key="index" v-show="show">{{item}}</span>
</div>
<!-- 搜索列表数据渲染 -->
<div class="course">
<!-- 跳转详情页 -->
<router-link
tag="div"
:to="{path:'/coursedetail',query:{id:item.id}}"
v-for="(item,index) in searchList"
:key="index"
class="courselist"
>
<p class="coursetitle">{{item.title}}</p>
<p class="coursetime">
<img src="../assets/img/time.png" />
<span>
{{ item.start_play_date|dateTime}}~{{ item.end_play_date | dateTime }}
|共{{item.total_periods}}课时
</span>
</p>
<p class="coursename" v-for="(teach,indexTeach) in item.teachers_list" :key="indexTeach">
<img :src="teach.teacher_avatar" />
<span>{{teach.teacher_name}}</span>
</p>
<p class="courseprice">
<span>{{item.sales_num}}人已报名</span>
<span>{{item.price|price}}</span>
</p>
</router-link>
</div>
</div>
</template>
js代码:
防抖功能使用到 lodash 工具库
地址链接 :
Lodash是一个一致性、模块化、高性能的 JavaScript 实用工具库。
下载:
npm install lodash
使用:
import _ from ‘lodash’
<script>
// 引入api封装好的接口
import { lessonList } from "../http/api";
// 引入lodash js库
import _ from "lodash";
// vant轻提示
import { Toast } from "vant";
export default {
name: "search",
data() {
return {
// 关键字
keywords: "",
// 数据列表
searchList: [],
// 显示隐藏
show: true,
// 搜索历史列表
hislist: []
};
},
created() {
// 定义数组接收本地存储的历史记录
let a = localStorage.hislist;
if (a) {
// 将数组转字符串
this.hislist = JSON.parse(a);
}
},
methods: {
// input监听事件
changevalue(e) {
// 获取到输入框的值
this.keywords = e.target.value;
// 判断
if (this.keywords.length > 0) {
this.show = false;
} else {
this.show = true;
this.searchList = [];
}
},
// 删除
del() {
this.hislist = [];
// 本地清除
localStorage.clear();
Toast.success("删除成功");
},
// 取消
quxiao() {
this.$router.push({
path: "/course"
});
},
// 返回上一步
back() {
this.$router.go(-1);
},
//搜索 加防抖(使用lodash插件库)
search: _.debounce(
function() {
//判断是否有重复
var index = this.hislist.findIndex(ele => {
return ele == this.keywords;
});
//如果有的话就删除重复
if (index != -1) {
this.hislist.splice(index, 1);
}
//向数组第一位添加
this.hislist.unshift(this.keywords);
//如果数组长度大于4 就删除最后一项
if (this.hislist.length > 4) {
this.hislist.splice(5, 1);
}
// 本地存储历史记录数组
localStorage.hislist = JSON.stringify(this.hislist);
// 请求api接口
lessonList({
// 传参数
page: 1,
limit: 10,
keywords: this.keywords
}).then(res => {
// console.log(res.data.data.list);
// 获取到数据进行赋值
this.searchList = res.data.data.list;
// console.log(this.searchList);
});
// this.keywords = "";
console.log("防抖");
},
3000,
{
leading: true, //指定在延迟开始前调用,默认false。
trailing: false //指定在延迟结束后调用,默认true。
}
)
}
};
</script>
css代码:
<style lang="scss" scoped>
.search {
width: 100%;
height: 14.33333vw;
line-height: 100px;
display: flex;
justify-content: space-between;
border-bottom: 2px solid gainsboro;
div:nth-of-type(1) {
margin-top: 5px;
margin-left: 20px;
img {
width: 35px;
}
}
div:nth-of-type(2) {
input {
border: none;
border-radius: 40px;
background: #e4e7ed;
width: 540px;
height: 60px;
text-indent: 30px;
font-size: 25px;
}
}
div:nth-of-type(3) {
margin-right: 30px;
font-size: 28px;
}
div:nth-of-type(4) {
margin-right: 30px;
font-size: 28px;
}
}
.course {
border: 1px solid #f0f2f5;
margin-top: 0px;
}
.history {
display: flex;
justify-content: space-between;
margin-top: 30px;
p:nth-of-type(1) {
font-size: 28px;
font-weight: bold;
margin-left: 30px;
}
p:nth-of-type(2) {
margin-right: 30px;
img {
width: 35px;
}
}
}
.hislist {
span {
display: inline-block;
background: #f7f7f7;
margin-left: 20px;
padding: 10px 20px 10px 20px;
border-radius: 20px;
}
}
.courselist {
width: 83%;
margin: 0 auto;
margin-top: 30px;
background: white;
border-radius: 20px;
height: 380px;
padding: 0px 25px;
.coursetitle {
font-size: 30px;
padding-top: 25px;
}
.coursetime {
margin-top: -25px;
img {
width: 24px;
vertical-align: -3px;
}
span {
font-size: 26px;
color: #666666;
}
}
.coursename {
margin-top: 50px;
img {
width: 50px;
vertical-align: -15px;
}
span {
font-size: 26px;
color: #666666;
margin-left: 20px;
}
}
.courseprice {
width: 100%;
margin: 0 auto;
border-top: 1px solid gainsboro;
margin-top: 30px;
padding-top: 15px;
span:nth-of-type(1) {
font-size: 25px;
color: #666666;
}
span:nth-of-type(2) {
font-size: 30px;
color: green;
margin-left: 430px;
}
}
}
</style>