Skip to content

Commit a5497ce

Browse files
committed
优化搜索体验
1 parent 5a7b19b commit a5497ce

File tree

1 file changed

+83
-35
lines changed

1 file changed

+83
-35
lines changed
Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,29 @@
11
<template>
22
<div style="display: inline-flex;">
3-
<Input size="small" :width="150" :placeholder="$t(`main_search_placeholder`)" v-model="input" @load="load">
3+
<Input
4+
size="small"
5+
:width="150"
6+
:placeholder="$t(`main_search_placeholder`)"
7+
v-model="input"
8+
@load="load"
9+
@keyup.enter="keyupEnter"
10+
@keyup.up="keyupUp"
11+
@keyup.down="keyupDown"
12+
@keyup.esc="close"
13+
>
414
<template #suffix>
515
<Icon name="search" :size="12"/>
616
</template>
717
</Input>
818
<ul class="ctool-search-block" v-if="isInput" ref="container">
9-
<li v-for="item in items" @click="click(item.tool,item.feature)" :key="`${item.tool}-${item.feature}`">{{ item.label }}</li>
19+
<li
20+
v-for="(item,index) in items"
21+
:class="index === selectIndex ? `ctool-search-active` : ''"
22+
@click="select(index)"
23+
:key="`${item.tool}-${item.feature}`"
24+
@mouseover="selectIndex = index"
25+
>{{ item.label }}
26+
</li>
1027
</ul>
1128
</div>
1229
</template>
@@ -15,40 +32,15 @@ import {toolKeywords} from "@/buildDataTemp";
1532
import {getTool, FeatureInterface} from "@/config";
1633
import useOperate from "@/store/operate";
1734
import useSetting from "@/store/setting";
35+
import {watch} from "vue";
1836
1937
const setting = useSetting()
2038
const operate = useOperate()
2139
let container = $ref<HTMLElement | null>(null);
2240
let input = $ref("")
2341
let inputElement = $ref<HTMLInputElement | null>(null);
2442
let isInput = $ref(false);
25-
26-
const load = (element: HTMLInputElement) => {
27-
inputElement = element
28-
element.addEventListener("focus", () => {
29-
isInput = true
30-
});
31-
document.addEventListener("click", (e: MouseEvent) => {
32-
if (
33-
element.contains(e.target as any)
34-
|| container?.contains(e.target as any)
35-
) {
36-
return;
37-
}
38-
isInput = false
39-
});
40-
}
41-
42-
const click = (tool, feature) => {
43-
const keyword = input
44-
input = ""
45-
if (tool === "") {
46-
return;
47-
}
48-
operate.redirectTool(tool, feature,'','',keyword)
49-
inputElement?.blur()
50-
isInput = false
51-
}
43+
let selectIndex = $ref(0)
5244
5345
const items = $computed(() => {
5446
let lists: FeatureInterface[]
@@ -63,7 +55,7 @@ const items = $computed(() => {
6355
]
6456
)
6557
)
66-
].slice(0, 10)
58+
]
6759
} else {
6860
lists = toolKeywords.filter((item) => item.search.join(",").includes(input.toLowerCase())).map(item => {
6961
return getTool(item.name).getFeature(item.feature)
@@ -72,7 +64,7 @@ const items = $computed(() => {
7264
if (lists.length === 0) {
7365
return [{label: $t(`main_ui_null`), tool: "", feature: ""}]
7466
}
75-
return lists.map(feature => {
67+
return lists.slice(0, 15).map(feature => {
7668
const tool = feature.tool
7769
return {
7870
label: `${$t(`tool_${tool.name}`)}${tool.isSimple() ? `` : ` - ${$t(`tool_${tool.name}_${feature.name}`)}`}`,
@@ -81,6 +73,62 @@ const items = $computed(() => {
8173
}
8274
})
8375
})
76+
77+
const open = () => {
78+
isInput = true
79+
selectIndex = 0
80+
}
81+
82+
const close = () => {
83+
input = ""
84+
isInput = false
85+
selectIndex = 0
86+
}
87+
88+
const load = (element: HTMLInputElement) => {
89+
inputElement = element
90+
element.addEventListener("focus", () => open());
91+
document.addEventListener("click", (e: MouseEvent) => {
92+
if (
93+
element.contains(e.target as any)
94+
|| container?.contains(e.target as any)
95+
) {
96+
return;
97+
}
98+
close()
99+
});
100+
}
101+
102+
const select = (index: number) => {
103+
if (items.length === 0 || items.length - 1 < index) {
104+
return;
105+
}
106+
const {tool, feature} = items[index]
107+
const keyword = input
108+
if (tool !== "") {
109+
operate.redirectTool(tool, feature, '', '', keyword)
110+
}
111+
inputElement?.blur();
112+
close();
113+
}
114+
115+
const keyupEnter = () => {
116+
select(selectIndex)
117+
}
118+
const keyupUp = () => {
119+
if (items.length === 0) {
120+
return;
121+
}
122+
selectIndex = selectIndex === 0 ? items.length - 1 : selectIndex - 1
123+
}
124+
const keyupDown = () => {
125+
if (items.length === 0) {
126+
return;
127+
}
128+
selectIndex = selectIndex === items.length - 1 ? 0 : selectIndex + 1
129+
}
130+
131+
watch(() => input, () => selectIndex = 0, {immediate: true})
84132
</script>
85133

86134
<style>
@@ -90,8 +138,6 @@ const items = $computed(() => {
90138
top: 28px;
91139
font-size: .875rem;
92140
width: 165px;
93-
max-height: 15rem;;
94-
overflow-y: auto;
95141
display: flex;
96142
flex-direction: column;
97143
border: var(--border-width) solid var(--dropdown-border-color);
@@ -101,19 +147,21 @@ const items = $computed(() => {
101147
color: var(--dropdown-color);
102148
white-space: nowrap;
103149
font-style: normal;
150+
margin-bottom: 0px;
104151
padding: 5px 0 0;
105152
}
106153
107154
.ctool-search-block li {
108155
cursor: pointer;
156+
list-style: none;
109157
width: 100%;
110158
color: var(--dropdown-color);
111159
padding-left: 10px;
112-
line-height: 2rem;
160+
line-height: 1.9rem;
113161
margin-bottom: 0;
114162
}
115163
116-
.ctool-search-block li:hover {
164+
.ctool-search-block li.ctool-search-active {
117165
background-color: var(--dropdown-hover-background-color);
118166
}
119167
</style>

0 commit comments

Comments
 (0)