feat: 页面懒加载 #98
@ -47,3 +47,9 @@
|
|||||||
currentPage.value = 1; // 重置页码
|
currentPage.value = 1; // 重置页码
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.el-tabs {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -4,11 +4,17 @@
|
|||||||
<h1 class="page-title">{{ $t('navigation.downloads') }}</h1>
|
<h1 class="page-title">{{ $t('navigation.downloads') }}</h1>
|
||||||
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
|
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
|
||||||
</div>
|
</div>
|
||||||
<div v-if="!pending" class="page-content">
|
<div class="page-content">
|
||||||
<file-card :file-id="id" :file="file" />
|
<el-skeleton
|
||||||
</div>
|
:loading="pending"
|
||||||
<div v-else>
|
:rows="6"
|
||||||
<el-skeleton :rows="6" animated />
|
animated
|
||||||
|
:throttle="{ leading: 500, trailing: 500 }"
|
||||||
|
>
|
||||||
|
<template #default>
|
||||||
|
<file-card :file-id="id" :file="file" />
|
||||||
|
</template>
|
||||||
|
</el-skeleton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,31 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<div v-if="!pending">
|
<div v-if="product">
|
||||||
<div v-if="product">
|
<!-- 面包屑导航 -->
|
||||||
<!-- 面包屑导航 -->
|
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
|
||||||
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
|
<!-- 产品详情内容 -->
|
||||||
<!-- 产品详情内容 -->
|
<product-header :product="product" />
|
||||||
<product-header :product="product" />
|
<!-- 产品详细描述 -->
|
||||||
<!-- 产品详细描述 -->
|
<product-detail :product="product" />
|
||||||
<product-detail :product="product" />
|
|
||||||
</div>
|
|
||||||
<!-- 未找到产品 -->
|
|
||||||
<div v-else class="not-found">
|
|
||||||
<not-found-result
|
|
||||||
:title="$t('product-not-found')"
|
|
||||||
:sub-title="$t('product-not-found-desc')"
|
|
||||||
:back-text="$t('back-to-products')"
|
|
||||||
:on-back="() => $router.push($localePath('/products'))"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="loading">
|
<!-- 未找到产品 -->
|
||||||
<el-skeleton style="--el-skeleton-circle-size: 400px">
|
<div v-else class="not-found">
|
||||||
<template #template>
|
<not-found-result
|
||||||
<el-skeleton-item variant="circle" />
|
:title="$t('product-not-found')"
|
||||||
</template>
|
:sub-title="$t('product-not-found-desc')"
|
||||||
</el-skeleton>
|
:back-text="$t('back-to-products')"
|
||||||
<el-skeleton :rows="5" animated />
|
:on-back="() => $router.push($localePath('/products'))"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -37,7 +27,7 @@
|
|||||||
// 获取路由参数
|
// 获取路由参数
|
||||||
const id = route.params.slug as string;
|
const id = route.params.slug as string;
|
||||||
|
|
||||||
const { data: product, pending, error } = await useProduct(id);
|
const { data: product, error } = await useProduct(id);
|
||||||
|
|
||||||
const breadcrumbItems = computed(() => [
|
const breadcrumbItems = computed(() => [
|
||||||
{ label: $t('navigation.home'), to: localePath('/') },
|
{ label: $t('navigation.home'), to: localePath('/') },
|
||||||
|
|||||||
@ -1,18 +1,33 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="search-page">
|
<div class="search-page">
|
||||||
<search-header v-model="keyword" />
|
<search-header v-model="keyword" />
|
||||||
<div v-if="loading" class="search-state">
|
<div class="search-state">
|
||||||
<el-skeleton :rows="4" animated />
|
<el-skeleton
|
||||||
</div>
|
:loading="loading"
|
||||||
<search-tabs v-else-if="hasResults" :search-items="searchItems" />
|
animated
|
||||||
<div v-else class="search-state">
|
:throttle="{ leading: 500, trailing: 500 }"
|
||||||
<el-empty
|
>
|
||||||
:description="
|
<template #template>
|
||||||
route.query.query
|
<el-skeleton-item
|
||||||
? $t('search.no-results', { query: route.query?.query })
|
v-for="i in 10"
|
||||||
: $t('search.no-query')
|
:key="i"
|
||||||
"
|
variant="rect"
|
||||||
/>
|
class="skeleton-item"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<template #default>
|
||||||
|
<search-tabs v-if="hasResults" :search-items="searchItems" />
|
||||||
|
<div v-else>
|
||||||
|
<el-empty
|
||||||
|
:description="
|
||||||
|
route.query.query
|
||||||
|
? $t('search.no-results', { query: route.query?.query })
|
||||||
|
: $t('search.no-query')
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-skeleton>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -96,7 +111,11 @@
|
|||||||
.search-state {
|
.search-state {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
padding: 3rem 0;
|
}
|
||||||
|
|
||||||
|
.skeleton-item {
|
||||||
|
height: 80px;
|
||||||
|
margin-bottom: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 640px) {
|
@media (max-width: 640px) {
|
||||||
|
|||||||
@ -1,23 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="page-container">
|
<div class="page-container">
|
||||||
<div v-if="!pending">
|
<div v-if="solution">
|
||||||
<div v-if="solution">
|
<div class="page-header">
|
||||||
<div class="page-header">
|
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
|
||||||
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
|
|
||||||
</div>
|
|
||||||
<solution-detail :solution="solution" />
|
|
||||||
</div>
|
|
||||||
<div v-else class="not-found">
|
|
||||||
<not-found-result
|
|
||||||
:title="$t('solution-not-found')"
|
|
||||||
:sub-title="$t('solution-not-found-desc')"
|
|
||||||
:back-text="$t('back-to-solutions')"
|
|
||||||
:on-back="() => $router.push($localePath('/solutions'))"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
<solution-detail :solution="solution" />
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="loading">
|
<div v-else class="not-found">
|
||||||
<el-skeleton :rows="5" animated />
|
<not-found-result
|
||||||
|
:title="$t('solution-not-found')"
|
||||||
|
:sub-title="$t('solution-not-found-desc')"
|
||||||
|
:back-text="$t('back-to-solutions')"
|
||||||
|
:on-back="() => $router.push($localePath('/solutions'))"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -29,7 +24,7 @@
|
|||||||
// 获取路由参数
|
// 获取路由参数
|
||||||
const id = route.params.slug as string;
|
const id = route.params.slug as string;
|
||||||
|
|
||||||
const { data: solution, pending, error } = await useSolution(id);
|
const { data: solution, error } = await useSolution(id);
|
||||||
|
|
||||||
const breadcrumbItems = computed(() => [
|
const breadcrumbItems = computed(() => [
|
||||||
{ label: $t('navigation.home'), to: localePath('/') },
|
{ label: $t('navigation.home'), to: localePath('/') },
|
||||||
|
|||||||
Reference in New Issue
Block a user