feat(web): add incremental rendering for model list to avoid lag with large providers(openrouter)

This commit is contained in:
Fodesu
2026-03-09 17:03:23 +08:00
committed by 晨苒
parent 3ddb4f361c
commit 93ddf3c6d4
3 changed files with 40 additions and 4 deletions
+3 -1
View File
@@ -185,7 +185,9 @@
"importSuccess": "Successfully imported {created} models, skipped {skipped}",
"importFailed": "Failed to import models",
"importClientType": "Model Client Type",
"importClientTypeHint": "Set default client type for imported models"
"importClientTypeHint": "Set default client type for imported models",
"showingCount": "Showing {count} of {total}",
"showMore": "Show More"
},
"provider": {
"add": "Add Provider",
+3 -1
View File
@@ -181,7 +181,9 @@
"importSuccess": "成功导入 {created} 个模型,跳过 {skipped} 个",
"importFailed": "导入模型失败",
"importClientType": "模型客户端类型",
"importClientTypeHint": "为导入的模型设置默认客户端类型"
"importClientTypeHint": "为导入的模型设置默认客户端类型",
"showingCount": "显示 {count} / {total}",
"showMore": "加载更多"
},
"provider": {
"add": "添加服务商",
@@ -32,7 +32,7 @@
<section class="flex flex-col gap-4">
<ModelItem
v-for="model in filteredModels"
v-for="model in displayedModels"
:key="model.id || `${model.llm_provider_id}:${model.model_id}`"
:model="model"
:delete-loading="deleteModelLoading"
@@ -41,6 +41,23 @@
/>
</section>
<div
v-if="hasMore"
class="flex flex-col items-center gap-2 pt-4"
>
<span class="text-xs text-muted-foreground">
{{ $t('models.showingCount', { count: displayLimit, total: filteredModels.length }) }}
</span>
<Button
variant="outline"
size="sm"
class="cursor-pointer"
@click="showMore"
>
{{ $t('models.showMore') }}
</Button>
</div>
<Empty
v-if="filteredModels.length === 0"
class="flex justify-center items-center py-8"
@@ -71,8 +88,9 @@
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { ref, computed, watch } from 'vue'
import {
Button,
Empty,
EmptyContent,
EmptyDescription,
@@ -88,6 +106,8 @@ import ImportModelsDialog from '@/components/import-models-dialog/index.vue'
import ModelItem from './model-item.vue'
import type { ModelsGetResponse } from '@memoh/sdk'
const PAGE_SIZE = 30
const props = defineProps<{
providerId: string | undefined
models: ModelsGetResponse[] | undefined
@@ -100,6 +120,7 @@ defineEmits<{
}>()
const searchQuery = ref('')
const displayLimit = ref(PAGE_SIZE)
const filteredModels = computed(() => {
if (!props.models) return []
@@ -111,4 +132,15 @@ const filteredModels = computed(() => {
return name.includes(keyword) || modelId.includes(keyword)
})
})
const displayedModels = computed(() => filteredModels.value.slice(0, displayLimit.value))
const hasMore = computed(() => displayLimit.value < filteredModels.value.length)
function showMore() {
displayLimit.value += PAGE_SIZE
}
watch(searchQuery, () => {
displayLimit.value = PAGE_SIZE
})
</script>