2024-06-28 01:01:05 +00:00
< template >
< div >
< el -select
ref = "headerSearchSelect"
v - model = "search"
: remote - method = "querySearch"
filterable
default - first - option
remote
: placeholder = "$t('快速搜索导航')"
style = "width: 100%;"
@ change = "change"
>
< el -option v -for = " option in options " :key ="option.item.path" :value ="option.item" : label = "option.item.title.join(' > ')" / >
< / e l - s e l e c t >
2024-06-28 01:28:47 +00:00
< div style = "margin-top: 20px;display: flex; flex-wrap: wrap; justify-content: flex-start; align-items: center; padding-top: 5px;" >
2024-06-28 01:01:05 +00:00
< el -button size = "mini" type = "text" plain v-for ="(quickItem,index) in quickActionList" :key="index" @click="change(quickItem)" > < span > { { quickItem . title } } < / span > < / e l - b u t t o n >
< / div >
< / div >
<!-- class = "header-search-select" -- >
<!-- @ click . stop = "click" -- >
< / template >
< script >
// fuse is a lightweight fuzzy-search module
// make search results more in line with expectations
import Fuse from 'fuse.js/dist/fuse.min.js'
import path from 'path'
import { listSimpleAction } from "@/api/system/sysActionStats" ;
export default {
name : 'HeaderSearch' ,
data ( ) {
return {
createdId : '0' ,
visible : false ,
search : '' ,
options : [ ] ,
searchPool : [ ] ,
show : false ,
fuse : undefined ,
quickActionList : [ ] ,
}
} ,
computed : {
routes ( ) {
return this . $store . getters . permission _routes
}
} ,
watch : {
routes ( ) {
this . searchPool = this . generateRoutes ( this . routes )
} ,
searchPool ( list ) {
this . initFuse ( list )
} ,
show ( value ) {
if ( value ) {
document . body . addEventListener ( 'click' , this . close )
} else {
document . body . removeEventListener ( 'click' , this . close )
}
}
} ,
mounted ( ) {
this . searchPool = this . generateRoutes ( this . routes ) ;
2024-06-28 01:28:47 +00:00
this . initQuickActionList ( ) ;
2024-06-28 01:01:05 +00:00
} ,
methods : {
initQuickActionList ( ) {
let queryParams = {
pageNum : 1 ,
pageSize : 20
} ;
listSimpleAction ( queryParams ) . then ( response => {
this . quickActionList = response . rows ;
} ) ;
} ,
click ( ) {
this . show = ! this . show
if ( this . show ) {
this . $refs . headerSearchSelect && this . $refs . headerSearchSelect . focus ( )
}
} ,
close ( ) {
this . $refs . headerSearchSelect && this . $refs . headerSearchSelect . blur ( )
this . options = [ ]
this . show = false
} ,
change ( val ) {
const path = val . path ;
if ( this . ishttp ( val . path ) ) {
// http(s):// 路径新窗口打开
const pindex = path . indexOf ( "http" ) ;
window . open ( path . substr ( pindex , path . length ) , "_blank" ) ;
} else {
this . $router . push ( val . path )
}
this . search = ''
this . options = [ ]
this . $nextTick ( ( ) => {
this . show = false
} )
2024-06-28 01:28:47 +00:00
this . initQuickActionList ( ) ;
2024-06-28 01:01:05 +00:00
} ,
initFuse ( list ) {
this . fuse = new Fuse ( list , {
shouldSort : true ,
threshold : 0.4 ,
location : 0 ,
distance : 100 ,
maxPatternLength : 32 ,
minMatchCharLength : 1 ,
keys : [ {
name : 'title' ,
weight : 0.7
} , {
name : 'path' ,
weight : 0.3
} ]
} )
} ,
// Filter out the routes that can be displayed in the sidebar
// And generate the internationalized title
generateRoutes ( routes , basePath = '/' , prefixTitle = [ ] ) {
let res = [ ]
for ( const router of routes ) {
// skip hidden router
if ( router . hidden ) { continue }
const data = {
path : ! this . ishttp ( router . path ) ? path . resolve ( basePath , router . path ) : router . path ,
title : [ ... prefixTitle ]
}
if ( router . meta && router . meta . title ) {
data . title = [ ... data . title , router . meta . title ]
if ( router . redirect !== 'noRedirect' ) {
// only push the routes with title
// special case: need to exclude parent router without redirect
res . push ( data )
}
}
// recursive child routes
if ( router . children ) {
const tempRoutes = this . generateRoutes ( router . children , data . path , data . title )
if ( tempRoutes . length >= 1 ) {
res = [ ... res , ... tempRoutes ]
}
}
}
return res
} ,
querySearch ( query ) {
if ( query !== '' ) {
this . options = this . fuse . search ( query )
} else {
this . options = [ ]
}
} ,
ishttp ( url ) {
return url . indexOf ( 'http://' ) !== - 1 || url . indexOf ( 'https://' ) !== - 1
}
}
}
< / script >
< style lang = "scss" >
. quick - menu - popover {
// background-color: #090d29!important;
// border-color: #146ebd!important;
background - color : # 0000001 c ! important ;
border - color : # 0000 ! important ;
padding : 2 px ! important ;
}
. quick - menu - popover . el - popover _ _title {
color : white ! important ;
}
. quick - menu - popover . popper _ _arrow {
display : none ! important ;
}
// .quick-menu-popover .popper__arrow::after {
// border-top-color: #090d29 !important;
// }
. header - search {
font - size : 0 ! important ;
. search - icon {
cursor : pointer ;
font - size : 18 px ;
vertical - align : middle ;
}
. header - search - select {
font - size : 18 px ;
transition : width 0.2 s ;
width : 0 ;
overflow : hidden ;
background : transparent ;
border - radius : 0 ;
display : inline - block ;
vertical - align : middle ;
: deep . el - input _ _inner {
border - radius : 0 ;
border : 0 ;
padding - left : 0 ;
padding - right : 0 ;
box - shadow : none ! important ;
border - bottom : 1 px solid # d9d9d9 ;
vertical - align : middle ;
}
}
& . show {
. header - search - select {
width : 210 px ;
margin - left : 10 px ;
}
}
}
< / style >