添加搜索框下拉建议功能,支持键盘导航和模糊搜索,优化输入框交互体验
This commit is contained in:
@ -3,7 +3,7 @@
|
|||||||
<d-layout>
|
<d-layout>
|
||||||
<d-content class="main-content">
|
<d-content class="main-content">
|
||||||
<div class="pt-8 px-12 relative hidden lg:block">
|
<div class="pt-8 px-12 relative hidden lg:block">
|
||||||
<d-input class="devui-input-demo__mt" size="lg" v-model="searchWord" @keyup.enter="search" placeholder="请输入">
|
<d-input class="devui-input-demo__mt" size="lg" v-model="searchWord" placeholder="请输入">
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
<d-select class="w-48" size="lg" v-model="broswer" :options="options"></d-select>
|
<d-select class="w-48" size="lg" v-model="broswer" :options="options"></d-select>
|
||||||
</template>
|
</template>
|
||||||
@ -11,6 +11,12 @@
|
|||||||
<d-icon name="search" style="font-size: inherit;" @click="search" />
|
<d-icon name="search" style="font-size: inherit;" @click="search" />
|
||||||
</template>
|
</template>
|
||||||
</d-input>
|
</d-input>
|
||||||
|
<div v-if="searchBox" class="absolute left-34 mt-2 z-10 bg-white text-sm text-gray-500 max-h-40 rounded-md shadow-md px-4 py-2 max-w-80">
|
||||||
|
<div class="flex p-2 pr-20 truncate rounded-md items-center hover:text-primary cursor-pointer"
|
||||||
|
:class="selecedIdx === idx ? 'text-white bg-primary' : ''" v-for="(i, idx) in searchItems"
|
||||||
|
:key="idx" @click="goExtra(i.menu_link)" @keyup.enter ="goExtra(i.menu_link)"
|
||||||
|
><span v-if="idx">导航:</span> {{i.menu_name }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 标签组 -->
|
<!-- 标签组 -->
|
||||||
<!-- <PerfectScrollbar class="w-full overflow-x-auto"> -->
|
<!-- <PerfectScrollbar class="w-full overflow-x-auto"> -->
|
||||||
@ -21,7 +27,8 @@
|
|||||||
<!-- </PerfectScrollbar> -->
|
<!-- </PerfectScrollbar> -->
|
||||||
<!-- 图片网格展示区域 -->
|
<!-- 图片网格展示区域 -->
|
||||||
<PerfectScrollbar class="" :style="navStyle">
|
<PerfectScrollbar class="" :style="navStyle">
|
||||||
<div ref="navcards" class="navcard grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 gap-5 pt-3 pb-6 px-2 lg:px-12">
|
<div ref="navcards"
|
||||||
|
class="navcard grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-6 gap-5 pt-3 pb-6 px-2 lg:px-12">
|
||||||
<d-card class="bg-[#ffffff80] h-24" v-for="(item, index) in navlist" :key="index"
|
<d-card class="bg-[#ffffff80] h-24" v-for="(item, index) in navlist" :key="index"
|
||||||
@click="goExtra(item.menu_link)" @contextmenu.prevent="handdleContextMenu($event, item)">
|
@click="goExtra(item.menu_link)" @contextmenu.prevent="handdleContextMenu($event, item)">
|
||||||
<template #content>
|
<template #content>
|
||||||
@ -162,6 +169,9 @@ const contentStyle: any = ref({})
|
|||||||
const navStyle: any = ref({})
|
const navStyle: any = ref({})
|
||||||
const searchWord: any = ref('')
|
const searchWord: any = ref('')
|
||||||
const broswer: any = ref('bing')
|
const broswer: any = ref('bing')
|
||||||
|
const searchItems: any = ref([])
|
||||||
|
const selecedIdx = ref(0)
|
||||||
|
const searchBox = ref(false)
|
||||||
const options = ref([
|
const options = ref([
|
||||||
{
|
{
|
||||||
name: '必应',
|
name: '必应',
|
||||||
@ -201,6 +211,67 @@ const tagList: any = ref([
|
|||||||
const usrLog = $store.log.useLogStore()
|
const usrLog = $store.log.useLogStore()
|
||||||
let timer: any = null;
|
let timer: any = null;
|
||||||
|
|
||||||
|
// 输入搜索内容时监听searchWord在navlist中模糊搜索
|
||||||
|
watch(searchWord, () => {
|
||||||
|
handdleInput()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function handdleInput() {
|
||||||
|
if (!searchWord.value) {
|
||||||
|
searchItems.value = []
|
||||||
|
searchBox.value = false
|
||||||
|
selecedIdx.value = 0
|
||||||
|
return
|
||||||
|
}
|
||||||
|
searchBox.value = true
|
||||||
|
selecedIdx.value = 0
|
||||||
|
const keyword = searchWord.value.toLowerCase()
|
||||||
|
searchItems.value = navlist.value.filter((item: any) =>
|
||||||
|
item.menu_name.toLowerCase().includes(keyword) ||
|
||||||
|
item.menu_link.toLowerCase().includes(keyword) ||
|
||||||
|
item.tag.toLowerCase().includes(keyword)
|
||||||
|
)
|
||||||
|
// 在searchItems第一个位置插入一条原本搜索
|
||||||
|
searchItems.value.unshift({
|
||||||
|
menu_name: `在${getDictValue(options.value, "value", broswer.value, "name")}中搜索"${searchWord.value}"`,
|
||||||
|
menu_link: getDictValue(options.value, "value", broswer.value, "url") + searchWord.value,
|
||||||
|
tag: ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function handdleKeyup(e: any) {
|
||||||
|
if (!searchBox.value) return
|
||||||
|
// console.log('>>> --> haddleDown --> idx:', e.keyCode)
|
||||||
|
// 向下箭头
|
||||||
|
if (e.keyCode == 40) {
|
||||||
|
if (selecedIdx.value < searchItems.value.length - 1) {
|
||||||
|
selecedIdx.value += 1
|
||||||
|
} else {
|
||||||
|
selecedIdx.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 向上箭头
|
||||||
|
else if (e.keyCode == 38) {
|
||||||
|
if (selecedIdx.value > 0) {
|
||||||
|
selecedIdx.value -= 1
|
||||||
|
} else {
|
||||||
|
selecedIdx.value = searchItems.value.length - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 回车键
|
||||||
|
else if (e.keyCode == 13) {
|
||||||
|
if (searchItems.value.length > 0) {
|
||||||
|
const selectedItem = searchItems.value[selecedIdx.value]
|
||||||
|
window.open(selectedItem.menu_link, "_BLANK")
|
||||||
|
searchBox.value = false
|
||||||
|
selecedIdx.value = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 2秒后自动隐藏菜单
|
// 2秒后自动隐藏菜单
|
||||||
const hideMenu = () => {
|
const hideMenu = () => {
|
||||||
timer = setTimeout(() => {
|
timer = setTimeout(() => {
|
||||||
@ -443,7 +514,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
navStyle.value = {
|
navStyle.value = {
|
||||||
// height: `calc(100vh - ${navcards.value.getBoundingClientRect().y}px - ${nav.navH}px)`,
|
// height: `calc(100vh - ${navcards.value.getBoundingClientRect().y}px - ${nav.navH}px)`,
|
||||||
height:`${window.innerHeight - navcards.value.getBoundingClientRect().y - 20}px`
|
height: `${window.innerHeight - navcards.value.getBoundingClientRect().y - 20}px`
|
||||||
}
|
}
|
||||||
tagList.value = [
|
tagList.value = [
|
||||||
{
|
{
|
||||||
@ -453,15 +524,17 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
getNavList()
|
getNavList()
|
||||||
window.addEventListener('resize', ()=>{
|
window.addEventListener('resize', () => {
|
||||||
contentStyle.value = {
|
contentStyle.value = {
|
||||||
height: `calc(100vh - ${nav.navH}px)`
|
height: `calc(100vh - ${nav.navH}px)`
|
||||||
}
|
}
|
||||||
navStyle.value = {
|
navStyle.value = {
|
||||||
height:`${window.innerHeight - navcards.value.getBoundingClientRect().top - 20}px`
|
height: `${window.innerHeight - navcards.value.getBoundingClientRect().top - 20}px`
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
window.addEventListener('keyup', (e: Event) => {
|
||||||
|
handdleKeyup(e)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user