仿京东官网搜索框,二次封装elementui实现下拉搜索框(效果如图)
- 实现鼠标点击输入框,显示历史记录栏、 热门搜索栏。
- 历史记录显示5个,localstorage存本地,去重后显示在第一个(重复不显示),超出5个删除最后一个
- 热门搜索栏默认显示10个
- 实现模糊搜索,输入关键字可显示与输入内容关联内容,若搜索无此内容,显示“搜索:xxx”
- 实现输入关联词,点击其他地方再回到搜索框,搜索框可显示上次输入内容
fix:
20220812修复输入关联词后,点击再回到搜索框,删除不掉上次输入内容的bug
20220831修复多次点击,已输入内容变灰色
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" version="1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=yes"/>
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit" />
<title>下拉搜索框 模糊搜索</title>
<style>
* {
margin: 0px;
padding: 0px;
box-sizing: border-box;
}
[v-cloak] {
display: none;
}
.el-input__icon {
display: none;
}
.el-input__prefix {
left: auto !important;
right: 0 !important;
}
.el-select-group {
display: flex;
padding: 10px 0 10px;
}
.el-select-group__title {
font-weight: 500;
font-size: 14px;
color: #111;
}
.el-select-group .el-select-dropdown__item {
margin-left: 20px;
max-width: 180px;
height: 24px;
line-height: 24px;
background: #EDEDED;
color: #666666;
border-radius: 2px;
text-align: center;
margin-bottom: 10px;
}
.el-select-dropdown__wrap {
max-height: auto !important;
}
.el-select-group__wrap:not(:last-of-type) {
padding-bottom: 0;
}
.el-select-group__wrap:not(:last-of-type)::after {
display: none;
}
.el-select-group .el-select-dropdown__item:hover{
color: #e1251b;
}
.el-popper .popper__arrow {
display: none;
}
.el-popper[x-placement^=bottom] {
margin-top: 0
}
.el-input--prefix .el-input__inner {
height: 54px;
border-radius: 6px;
}
.el-select .el-input.is-focus .el-input__inner {
border-color: #e1251b;
}
.search-empty {
padding: 20px;
font-size:14px;
color: #666666;
cursor: pointer;
}
.search-empty:hover {
color: #e1251b;
}
.el-select .el-input__inner:hover {
cursor: text !important;
}
.search-btn {
width: 124px;
height: 54px;
background: #e1251b;
color:#fff;
border-radius: 0 6px 6px 0;
border: 1px solid #e1251b;
}
.search-btn:hover {
background-color: #c81623;
color:#fff;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<template>
<el-select
filterable
v-model="searchValue"
placeholder="Search..."
@focus="searchFocus"
@click="searchFocus"
@change="searcChange"
ref="elSelec"
:filter-method="filterMethod"
@keyup.enter.native="onSearch">
<template slot="prefix">
<el-button @click="onSearch" icon="el-icon-search" class="search-btn">搜索</el-button>
</template>
<template slot="empty">
<div class="search-empty" @click="onSearch">搜索 “{{this.searchValue}}”</div>
</template>
<div v-if="isShowHistroy">
<el-option-group label="历史记录">
<el-option v-for="(item, index) in historyOptions" :key="index" :label="item" :value="item"></el-option>
</el-option-group>
<el-option-group label="热门城市" >
<div>
<el-option v-for="(item, index) in hotOptions" :key="index" :label="item" :value="item"></el-option>
</div>
</el-option-group>
</div>
<div>
<el-option v-for="(item, index) in options" :key="index" :label="item" :value="item"></el-option>
</div>
</el-select>
</template>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
var V = new Vue({
el: "#app",
data: function () {
return {
searchValue: '',
isShowHistroy: false,
historyOptions: [], // 历史搜索
hotOptions: ['北京', '上海', '乌鲁木齐', '昆明', '南宁', '广州', '厦门', '西安', '长沙', '贵阳'], // 热门搜索
options: [],
// 词库
optionsFilter: ['北京', '上海', '广州广州广州', '广州', '杭州', '西安', '昆明', '南宁', '贵州南宁', '南宁南宁北京', '南宁上海', '南宁广州广州广州', '广州', '杭州', '西安', '昆明', '南宁', '贵州'], // 联系词库
}
},
created() {
},
mounted() {
this.historyOptions = JSON.parse(localStorage.getItem("histroyOptions")) || []
},
updated() {},
destroyed() {},
watch: {},
computed: {},
methods: {
// 历史记录存本地
saveLocalStorage(val) {
if (val) {
this.historyOptions.unshift(val)
this.historyOptions = [...new Set(this.historyOptions)]
if (this.historyOptions.length > 5) {
this.historyOptions.pop()
}
localStorage.setItem('histroyOptions', JSON.stringify(this.historyOptions))
}
},
// 搜索跳转
onSearch() {
console.log(this.searchValue)
this.saveLocalStorage(this.searchValue)
window.location.href = `test.html?keywork=${this.searchValue}`
},
// input获取焦点
searchFocus(e) {
let value = this.searchValue
if (value) {
// 已输入内容 重新赋值到搜素框
setTimeout(() => {
let input = this.$refs.elSelec.$children[0].$refs.input
input.value = value
let that = this
// 监听input的是输入值变化
input.oninput = function() {
that filterMethod(this.value)
}
})
} else {
this.isShowHistroy = true
}
},
// 选中
searcChange(val) {
this.isShowHistroy = false
this.saveLocalStorage(val)
window.location.href = `test.html?keywork=${val}`
},
// 自定义过滤
filterMethod(val) {
console.log(val, '输入的值')
if (val) {
this.isShowHistroy = false
this.searchValue = val
let filterResult = []
let originalData = JSON.parse(JSON.stringify(this.optionsFilter)) // 词库
originalData.filter((item) => {
if (item.includes(val)) {
filterResult.push(item)
}
})
this.options = filterResult.length filterResult : []
} else {
this.options = []
this.isShowHistroy = true
this.searchValue = ''
}
},
},
});
</script>
</html>