parent
5a7c8c7b48
commit
e9dc3e8d86
@ -1,151 +0,0 @@ |
|||||||
<template> |
|
||||||
<div :class="{'show':show}" class="header-search"> |
|
||||||
<i class="el-icon-search navbar-icon" title="快捷搜索" @click.stop="click"/> |
|
||||||
|
|
||||||
<el-select |
|
||||||
ref="headerSearchSelect" |
|
||||||
v-model="search" |
|
||||||
class="header-search-select" |
|
||||||
:remote-method="querySearch" |
|
||||||
default-first-option |
|
||||||
filterable |
|
||||||
placeholder="搜索页面" |
|
||||||
remote |
|
||||||
popper-append-to-body |
|
||||||
@change="change" |
|
||||||
> |
|
||||||
<el-option |
|
||||||
v-for="item in options" |
|
||||||
:key="item.path" |
|
||||||
:label="item.title.join(' > ')" |
|
||||||
:value="item.path" |
|
||||||
/> |
|
||||||
</el-select> |
|
||||||
</div> |
|
||||||
</template> |
|
||||||
|
|
||||||
<script> |
|
||||||
import Fuse from 'fuse.js' |
|
||||||
|
|
||||||
export default { |
|
||||||
name: 'HeaderSearch', |
|
||||||
|
|
||||||
data() { |
|
||||||
return { |
|
||||||
search: '', |
|
||||||
options: [], |
|
||||||
searchPool: [], |
|
||||||
show: false, |
|
||||||
fuse: null |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
computed: { |
|
||||||
routes() { |
|
||||||
return this.$store.state.resource.routes |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
watch: { |
|
||||||
routes() { |
|
||||||
this.searchPool = this.generateRoutes(this.routes) |
|
||||||
this.initFuse(this.searchPool) |
|
||||||
}, |
|
||||||
|
|
||||||
show(value) { |
|
||||||
if (value) document.body.addEventListener('click', this.close) |
|
||||||
else document.body.removeEventListener('click', this.close) |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
methods: { |
|
||||||
click() { |
|
||||||
this.show = !this.show |
|
||||||
if (this.show) this.$refs.headerSearchSelect.focus() |
|
||||||
}, |
|
||||||
|
|
||||||
close() { |
|
||||||
this.$refs.headerSearchSelect.blur() |
|
||||||
this.search = '' |
|
||||||
this.options = [] |
|
||||||
this.show = false |
|
||||||
}, |
|
||||||
|
|
||||||
change(val) { |
|
||||||
this.close() |
|
||||||
this.$router.push(val).catch(() => ({})) |
|
||||||
}, |
|
||||||
|
|
||||||
initFuse(list) { |
|
||||||
this.fuse = new Fuse(list, { |
|
||||||
shouldSort: true, |
|
||||||
threshold: 0.4, |
|
||||||
location: 0, |
|
||||||
distance: 100, |
|
||||||
maxPatternLength: 32, |
|
||||||
minMatchCharLength: 1, |
|
||||||
keys: ['title'] |
|
||||||
}) |
|
||||||
}, |
|
||||||
|
|
||||||
generateRoutes(routes, prefixTitle = []) { |
|
||||||
let res = [] |
|
||||||
for (const route of routes) { |
|
||||||
const data = {path: route.fullPath, title: [...prefixTitle]} |
|
||||||
|
|
||||||
if (route.meta && route.meta.title) { |
|
||||||
data.title = [...data.title, route.meta.title] |
|
||||||
if (route.name) res.push(data) |
|
||||||
} |
|
||||||
|
|
||||||
if (route.children) { |
|
||||||
const tempRoutes = this.generateRoutes(route.children, data.title) |
|
||||||
if (tempRoutes.length > 0) res.push(...tempRoutes) |
|
||||||
} |
|
||||||
} |
|
||||||
return res |
|
||||||
}, |
|
||||||
|
|
||||||
querySearch(query) { |
|
||||||
this.options = query ? this.fuse.search(query) : [] |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
mounted() { |
|
||||||
this.searchPool = this.generateRoutes(this.routes) |
|
||||||
this.initFuse(this.searchPool) |
|
||||||
} |
|
||||||
} |
|
||||||
</script> |
|
||||||
|
|
||||||
<style lang="scss"> |
|
||||||
.header-search { |
|
||||||
.header-search-select { |
|
||||||
font-size: 18px; |
|
||||||
transition: width 0.2s; |
|
||||||
width: 0; |
|
||||||
overflow: hidden; |
|
||||||
background: transparent; |
|
||||||
border-radius: 0; |
|
||||||
display: inline-block; |
|
||||||
vertical-align: middle; |
|
||||||
|
|
||||||
.el-input__inner { |
|
||||||
border-radius: 0; |
|
||||||
border: 0; |
|
||||||
padding-left: 0; |
|
||||||
padding-right: 0; |
|
||||||
box-shadow: none !important; |
|
||||||
border-bottom: 1px solid #d9d9d9; |
|
||||||
vertical-align: middle; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
&.show { |
|
||||||
.header-search-select { |
|
||||||
width: 210px; |
|
||||||
margin-left: 10px; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
</style> |
|
||||||
Loading…
Reference in new issue