-
-
-
-
-
@@ -65,36 +97,40 @@ const routes = computed(() => usePermissionStore().defaultRoutes)
function click() {
show.value = !show.value
if (show.value) {
- headerSearchSelectRef.value && headerSearchSelectRef.value.focus()
options.value = searchPool.value
}
}
+function onDialogOpened() {
+ nextTick(() => {
+ headerSearchSelectRef.value && headerSearchSelectRef.value.focus()
+ })
+}
+
function close() {
headerSearchSelectRef.value && headerSearchSelectRef.value.blur()
search.value = ''
- options.value = []
+ options.value = searchPool.value
show.value = false
activeIndex.value = -1
}
function change(val) {
- const path = val.path
+ const p = val.path
const query = val.query
- if (isHttp(path)) {
+ if (isHttp(p)) {
// http(s):// 路径新窗口打开
- const pindex = path.indexOf("http")
- window.open(path.substr(pindex, path.length), "_blank")
+ const pindex = p.indexOf("http")
+ window.open(p.substr(pindex, p.length), "_blank")
} else {
if (query) {
- router.push({ path: path, query: JSON.parse(query) })
+ router.push({ path: p, query: JSON.parse(query) })
} else {
- router.push(path)
+ router.push(p)
}
}
-
search.value = ''
- options.value = []
+ options.value = searchPool.value
nextTick(() => {
show.value = false
})
@@ -103,8 +139,7 @@ function change(val) {
function initFuse(list) {
fuse.value = new Fuse(list, {
shouldSort: true,
- threshold: 0.4,
- location: 0,
+ threshold: 0.2,
distance: 100,
minMatchCharLength: 1,
keys: [{
@@ -117,13 +152,9 @@ function initFuse(list) {
})
}
-// Filter out the routes that can be displayed in the sidebar
-// And generate the internationalized title
function generateRoutes(routes, basePath = '', prefixTitle = []) {
let res = []
-
for (const r of routes) {
- // skip hidden router
if (r.hidden) { continue }
const p = r.path.length > 0 && r.path[0] === '/' ? r.path : '/' + r.path
const data = {
@@ -131,21 +162,16 @@ function generateRoutes(routes, basePath = '', prefixTitle = []) {
title: [...prefixTitle],
icon: ''
}
-
if (r.meta && r.meta.title) {
data.title = [...data.title, r.meta.title]
data.icon = r.meta.icon
if (r.redirect !== "noRedirect") {
- // only push the routes with title
- // special case: need to exclude parent router without redirect
res.push(data)
}
}
if (r.query) {
data.query = r.query
}
-
- // recursive child routes
if (r.children) {
const tempRoutes = generateRoutes(r.children, data.path, data.title)
if (tempRoutes.length >= 1) {
@@ -159,7 +185,18 @@ function generateRoutes(routes, basePath = '', prefixTitle = []) {
function querySearch(query) {
activeIndex.value = -1
if (query !== '') {
- options.value = fuse.value.search(query).map((item) => item.item) ?? searchPool.value
+ const q = query.toLowerCase()
+ const pathMatches = searchPool.value.filter(item =>
+ item.path.toLowerCase().includes(q)
+ )
+ const fuseMatches = fuse.value.search(query).map(item => item.item)
+ const merged = [...pathMatches]
+ fuseMatches.forEach(item => {
+ if (!merged.find(m => m.path === item.path)) {
+ merged.push(item)
+ }
+ })
+ options.value = merged
} else {
options.value = searchPool.value
}
@@ -187,6 +224,18 @@ function selectActiveResult() {
}
}
+function highlightText(text) {
+ if (!text) return ''
+ if (!search.value) return text
+ const keyword = escapeRegExp(search.value)
+ const reg = new RegExp(`(${keyword})`, 'gi')
+ return text.replace(reg, '$1')
+}
+
+function escapeRegExp(str) {
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
+}
+
onMounted(() => {
searchPool.value = generateRoutes(routes.value)
})
@@ -197,6 +246,20 @@ watch(searchPool, (list) => {