refactor: 将各个页面的面包屑导航提取为单独组件AppBreadcrumb

This commit is contained in:
2025-10-28 16:16:57 +08:00
parent dc90e1045b
commit c6e0ea2a47
11 changed files with 116 additions and 157 deletions

View File

@ -0,0 +1,21 @@
<template>
<el-breadcrumb separator="/">
<el-breadcrumb-item
v-for="(item, index) in items"
:key="index"
class="text-md opacity-50"
>
<NuxtLink v-if="item.to" :to="item.to">{{ item.label }}</NuxtLink>
<span v-else>{{ item.label }}</span>
</el-breadcrumb-item>
</el-breadcrumb>
</template>
<script setup lang="ts">
defineProps({
items: {
type: Array as () => Array<{ label: string; to?: string }>,
required: true,
},
});
</script>

View File

@ -1,18 +1,7 @@
<template> <template>
<div class="page-container"> <div class="page-container">
<div v-if="!pending"> <div v-if="!pending">
<el-breadcrumb class="breadcrumb" separator="/"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">
{{ $t('navigation.home') }}
</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/about')">
{{ $t('navigation.about-us') }}
</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
<div class="content"> <div class="content">
<markdown-renderer :content="content.content || ''" /> <markdown-renderer :content="content.content || ''" />
@ -38,6 +27,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const localePath = useLocalePath();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.about-us') },
];
const { data, pending, error } = await useCompanyProfile(); const { data, pending, error } = await useCompanyProfile();
const content = computed(() => toCompanyProfileView(data.value)); const content = computed(() => toCompanyProfileView(data.value));

View File

@ -2,18 +2,7 @@
<div class="page-container"> <div class="page-container">
<div class="page-header"> <div class="page-header">
<h1 class="page-title">文件下载</h1> <h1 class="page-title">文件下载</h1>
<el-breadcrumb class="breadcrumb"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/products')">{{
$t('navigation.downloads')
}}</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div v-if="!pending" class="page-content"> <div v-if="!pending" class="page-content">
<el-card shadow="hover" class="p-4"> <el-card shadow="hover" class="p-4">
@ -60,6 +49,12 @@
<script setup lang="ts"> <script setup lang="ts">
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const localePath = useLocalePath();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.downloads'), to: localePath('/downloads') },
];
// 获取路由参数 // 获取路由参数
const id = computed(() => route.params.id as string); const id = computed(() => route.params.id as string);

View File

@ -3,21 +3,7 @@
<div v-if="!pending"> <div v-if="!pending">
<div v-if="product"> <div v-if="product">
<!-- 面包屑导航 --> <!-- 面包屑导航 -->
<el-breadcrumb class="breadcrumb" separator="/"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/products')">{{
$t('navigation.products')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opactiy-50">{{
product.name
}}</el-breadcrumb-item>
</el-breadcrumb>
<!-- 产品详情内容 --> <!-- 产品详情内容 -->
<div class="product-header"> <div class="product-header">
@ -87,7 +73,10 @@
:sub-title="$t('product-not-found-desc')" :sub-title="$t('product-not-found-desc')"
> >
<template #extra> <template #extra>
<el-button type="primary" @click="$router.push('/products')"> <el-button
type="primary"
@click="$router.push($localePath('/products'))"
>
{{ $t('back-to-products') }} {{ $t('back-to-products') }}
</el-button> </el-button>
</template> </template>
@ -107,6 +96,7 @@
<script setup lang="ts"> <script setup lang="ts">
const route = useRoute(); const route = useRoute();
const localePath = useLocalePath();
const { getImageUrl } = useDirectusImage(); const { getImageUrl } = useDirectusImage();
@ -115,17 +105,22 @@
const { data, pending, error } = await useProduct(id.value); const { data, pending, error } = await useProduct(id.value);
console.log('Raw Data: ', data.value);
const rawProduct = computed(() => data.value ?? null); const rawProduct = computed(() => data.value ?? null);
const product = computed(() => { const product = computed(() => {
if (rawProduct.value === null) {
return null;
}
return toProductView(rawProduct.value); return toProductView(rawProduct.value);
}); });
console.log('View Data: ', product.value);
const activeName = ref('details'); // 默认选中概览标签 const activeName = ref('details'); // 默认选中概览标签
const breadcrumbItems = computed(() => [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.products'), to: localePath('/products') },
{ label: product.value?.name || '' },
]);
watch(error, (value) => { watch(error, (value) => {
if (value) { if (value) {
console.error('数据获取失败: ', value); console.error('数据获取失败: ', value);

View File

@ -2,18 +2,7 @@
<div class="page-container"> <div class="page-container">
<div class="page-header"> <div class="page-header">
<h1 class="page-title">{{ $t('our-products') }}</h1> <h1 class="page-title">{{ $t('our-products') }}</h1>
<el-breadcrumb class="breadcrumb"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/products')">{{
$t('navigation.products')
}}</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div v-if="!pending" class="page-content"> <div v-if="!pending" class="page-content">
<div class="products-container"> <div class="products-container">
@ -45,12 +34,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const localePath = useLocalePath();
const { getImageUrl } = useDirectusImage(); const { getImageUrl } = useDirectusImage();
const { data, pending, error } = useProductList(); const { data, pending, error } = useProductList();
const activeNames = ref<string[]>([]); const activeNames = ref<string[]>([]);
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.products') },
];
const productsRaw = computed(() => data.value ?? []); const productsRaw = computed(() => data.value ?? []);
const products = computed(() => const products = computed(() =>
productsRaw.value.map((item) => toProductListView(item)) productsRaw.value.map((item) => toProductListView(item))

View File

@ -3,21 +3,7 @@
<div v-if="!pending"> <div v-if="!pending">
<div v-if="solution"> <div v-if="solution">
<div class="page-header"> <div class="page-header">
<el-breadcrumb class="breadcrumb" separator="/"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/solutions')">{{
$t('navigation.solutions')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">{{
solution.title
}}</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div class="page-content"> <div class="page-content">
<div class="solution-info"> <div class="solution-info">
@ -42,7 +28,10 @@
:sub-title="$t('solution-not-found-desc')" :sub-title="$t('solution-not-found-desc')"
> >
<template #extra> <template #extra>
<el-button type="primary" @click="$router.push('/solutions')"> <el-button
type="primary"
@click="$router.push($localePath('/solutions'))"
>
{{ $t('back-to-solutions') }} {{ $t('back-to-solutions') }}
</el-button> </el-button>
</template> </template>
@ -57,17 +46,25 @@
<script setup lang="ts"> <script setup lang="ts">
const route = useRoute(); const route = useRoute();
const localePath = useLocalePath();
// 获取路由参数(documentId) // 获取路由参数(documentId)
const id = computed(() => route.params.slug as string); const id = computed(() => route.params.slug as string);
const { data, pending, error } = await useSolution(id.value); const { data, pending, error } = await useSolution(id.value);
console.log('RawData: ', data.value); const solution = computed(() => {
const process = toSolutionView(data.value); if (!data.value) {
console.log('Processed Solution: ', process); return null;
}
return toSolutionView(data.value);
});
const solution = computed(() => toSolutionView(data.value)); const breadcrumbItems = computed(() => [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.solutions'), to: localePath('/solutions') },
{ label: solution.value ? solution.value.title : '' },
]);
watch(error, (value) => { watch(error, (value) => {
if (value) { if (value) {

View File

@ -2,18 +2,7 @@
<div class="page-container"> <div class="page-container">
<div class="page-header"> <div class="page-header">
<h1 class="page-title">{{ $t('learn-our-solutions') }}</h1> <h1 class="page-title">{{ $t('learn-our-solutions') }}</h1>
<el-breadcrumb class="breadcrumb"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/solutions')">{{
$t('navigation.solutions')
}}</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div v-if="!pending" class="solutions-container"> <div v-if="!pending" class="solutions-container">
<el-tabs v-model="activeName" class="solutions-tabs"> <el-tabs v-model="activeName" class="solutions-tabs">
@ -55,8 +44,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const localePath = useLocalePath();
const { getImageUrl } = useDirectusImage(); const { getImageUrl } = useDirectusImage();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.solutions') },
];
const { data, pending, error } = await useSolutionList(); const { data, pending, error } = await useSolutionList();
const solutionsRaw = computed(() => data.value ?? []); const solutionsRaw = computed(() => data.value ?? []);
@ -66,8 +61,6 @@
const activeName = ref<string>('all'); const activeName = ref<string>('all');
console.log('Processed Data', solutions.value);
// 按类型分组 // 按类型分组
const groupedSolutions = computed(() => { const groupedSolutions = computed(() => {
const gourps: Record<string, SolutionListView[]> = {}; const gourps: Record<string, SolutionListView[]> = {};

View File

@ -3,23 +3,7 @@
<support-tabs model-value="contact-us" /> <support-tabs model-value="contact-us" />
<div class="page-header"> <div class="page-header">
<h1 class="page-title">{{ $t('navigation.contact-info') }}</h1> <h1 class="page-title">{{ $t('navigation.contact-info') }}</h1>
<el-breadcrumb class="breadcrumb" separator="/"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">
{{ $t('navigation.home') }}
</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support')">
{{ $t('navigation.support') }}
</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support/contact-us')">
{{ $t('navigation.contact-info') }}
</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div v-if="!pending" class="page-content"> <div v-if="!pending" class="page-content">
@ -32,6 +16,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
const localePath = useLocalePath();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.support'), to: localePath('/support') },
{ label: $t('navigation.contact-info') },
];
const { data, pending, error } = await useContactInfo(); const { data, pending, error } = await useContactInfo();
const content = computed(() => toContactInfoView(data.value)); const content = computed(() => toContactInfoView(data.value));

View File

@ -7,23 +7,7 @@
<support-tabs model-value="documents" /> <support-tabs model-value="documents" />
<div class="page-header"> <div class="page-header">
<h1 class="page-title">{{ $t('navigation.documents') }}</h1> <h1 class="page-title">{{ $t('navigation.documents') }}</h1>
<el-breadcrumb class="breadcrumb" separator="/"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support')">{{
$t('navigation.support')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support/documents')">{{
$t('navigation.documents')
}}</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div class="document-category"> <div class="document-category">
<el-row :gutter="12"> <el-row :gutter="12">
@ -78,6 +62,13 @@
<script setup lang="ts"> <script setup lang="ts">
import { Search } from '@element-plus/icons-vue'; import { Search } from '@element-plus/icons-vue';
const localePath = useLocalePath();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.support'), to: localePath('/support') },
{ label: $t('navigation.documents') },
];
const { data, pending, error } = await useDocumentList(); const { data, pending, error } = await useDocumentList();
const documents = computed( const documents = computed(

View File

@ -7,23 +7,7 @@
<support-tabs model-value="faq" /> <support-tabs model-value="faq" />
<div class="page-header"> <div class="page-header">
<h1 class="page-title">{{ $t('navigation.faq') }}</h1> <h1 class="page-title">{{ $t('navigation.faq') }}</h1>
<el-breadcrumb class="breadcrumb" separator="/"> <app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support')">{{
$t('navigation.support')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support/faq')">{{
$t('navigation.faq')
}}</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div> </div>
<div class="question-category"> <div class="question-category">
@ -79,6 +63,14 @@
<script setup lang="ts"> <script setup lang="ts">
import { Search } from '@element-plus/icons-vue'; import { Search } from '@element-plus/icons-vue';
const localePath = useLocalePath();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.support'), to: localePath('/support') },
{ label: $t('navigation.faq') },
];
const { data, pending, error } = await useQuestionList(); const { data, pending, error } = await useQuestionList();
const questions = computed( const questions = computed(

View File

@ -1,22 +1,11 @@
<template> <template>
<div class="page-container"> <div class="page-container">
<support-tabs /> <support-tabs />
<div class="page-header">
<h1 class="page-title">{{ $t('navigation.support') }}</h1>
<app-breadcrumb class="breadcrumb" :items="breadcrumbItems" />
</div>
<div class="page-content"> <div class="page-content">
<div class="page-header">
<h1 class="page-title">{{ $t('navigation.support') }}</h1>
<el-breadcrumb class="breadcrumb" separator="/">
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/')">{{
$t('navigation.home')
}}</NuxtLink>
</el-breadcrumb-item>
<el-breadcrumb-item class="text-md opacity-50">
<NuxtLink :to="$localePath('/support')">{{
$t('navigation.support')
}}</NuxtLink>
</el-breadcrumb-item>
</el-breadcrumb>
</div>
<section style="margin-bottom: 2rem"> <section style="margin-bottom: 2rem">
<p> <p>
金申机械制造有限公司致力于为客户提供优质的产品与服务针对纸管机分纸机纸吸管等产品我们提供全方位的售后服务确保客户能够安心地使用我们的产品 金申机械制造有限公司致力于为客户提供优质的产品与服务针对纸管机分纸机纸吸管等产品我们提供全方位的售后服务确保客户能够安心地使用我们的产品
@ -109,7 +98,13 @@
</div> </div>
</template> </template>
<script setup lang="ts"></script> <script setup lang="ts">
const localePath = useLocalePath();
const breadcrumbItems = [
{ label: $t('navigation.home'), to: localePath('/') },
{ label: $t('navigation.support') },
];
</script>
<style scoped> <style scoped>
.page-container { .page-container {
@ -119,6 +114,7 @@
.page-header { .page-header {
display: flex; display: flex;
padding: 2rem 2rem 0rem;
} }
.page-title { .page-title {