Skip to content

Commit 43a7196

Browse files
xunxun1982tbphp
andauthored
feat: Group list scroll positioning (#284)
* 当选中一个分组或页面加载时,分组列表会自动滚动,确保所选分组始终处于可见区域。优化了在分组数量过多导致列表出现滚动条时的用户体验,避免了手动滚动的麻烦。 * 重构了自动滚动功能的实现细节。通过将 `watch` 监听器从深度监听整个对象优化为仅监听选中项的 ID,提升了组件性能。 * style: ES Lint --------- Co-authored-by: tbphp <[email protected]>
1 parent 59cc826 commit 43a7196

File tree

1 file changed

+30
-1
lines changed

1 file changed

+30
-1
lines changed

web/src/components/keys/GroupList.vue

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import type { Group } from "@/types/models";
33
import { getGroupDisplayName } from "@/utils/display";
44
import { Add, Search } from "@vicons/ionicons5";
55
import { NButton, NCard, NEmpty, NInput, NSpin, NTag } from "naive-ui";
6-
import { computed, ref } from "vue";
6+
import { computed, ref, watch } from "vue";
77
import { useI18n } from "vue-i18n";
88
import GroupFormModal from "./GroupFormModal.vue";
99
@@ -29,6 +29,8 @@ const emit = defineEmits<Emits>();
2929
3030
const searchText = ref("");
3131
const showGroupModal = ref(false);
32+
// 存储分组项 DOM 元素的引用
33+
const groupItemRefs = ref(new Map());
3234
3335
// 过滤后的分组列表
3436
const filteredGroups = computed(() => {
@@ -43,6 +45,28 @@ const filteredGroups = computed(() => {
4345
);
4446
});
4547
48+
// 监听选中项 ID 的变化,并自动滚动到该项
49+
watch(
50+
() => props.selectedGroup?.id,
51+
id => {
52+
if (!id || props.groups.length === 0) {
53+
return;
54+
}
55+
56+
const element = groupItemRefs.value.get(id);
57+
if (element) {
58+
element.scrollIntoView({
59+
behavior: "smooth", // 平滑滚动
60+
block: "nearest", // 将元素滚动到最近的边缘
61+
});
62+
}
63+
},
64+
{
65+
flush: "post", // 确保在 DOM 更新后执行回调
66+
immediate: true, // 立即执行一次以处理初始加载
67+
}
68+
);
69+
4670
function handleGroupClick(group: Group) {
4771
emit("group-select", group);
4872
}
@@ -107,6 +131,11 @@ function handleGroupCreated(group: Group) {
107131
class="group-item"
108132
:class="{ active: selectedGroup?.id === group.id }"
109133
@click="handleGroupClick(group)"
134+
:ref="
135+
el => {
136+
if (el) groupItemRefs.set(group.id, el);
137+
}
138+
"
110139
>
111140
<div class="group-icon">
112141
<span v-if="group.channel_type === 'openai'">🤖</span>

0 commit comments

Comments
 (0)