商品分页完善,首页高亮显示所在界面

This commit is contained in:
puzvv
2025-12-31 00:12:06 +08:00
parent fe1fd57c82
commit f9fd7f75e7
2 changed files with 151 additions and 34 deletions

View File

@@ -1,10 +1,11 @@
<script lang="ts" setup>
import { ref, computed } from "vue";
import { useRouter } from "vue-router";
import { useRouter, useRoute } from "vue-router";
import { useUserStore } from "@/stores/UserStore";
import { ElMessage } from "element-plus";
const router = useRouter();
const route = useRoute(); // 添加路由实例
const userStore = useUserStore();
const isMobileMenuOpen = ref(false);
@@ -23,6 +24,20 @@ const userNickname = computed(() => {
return userStore.userInfo?.nickname || userStore.userInfo?.username || "用户";
});
// 计算属性:判断当前路由
const currentRoute = computed(() => {
return route.path;
});
// 检查当前路由是否匹配指定路径
const isActiveRoute = (path: string) => {
if (path === "/") {
// 对于首页,需要精确匹配或只匹配子路径
return currentRoute.value === "/" || currentRoute.value.startsWith("/home");
}
return currentRoute.value.startsWith(path);
};
// 跳转登录页
const goToLogin = () => {
router.push("/user/login");
@@ -83,27 +98,44 @@ const goToProductManage = () => {
<nav class="hidden md:flex items-center space-x-8">
<a
href="#"
class="text-gray-600 hover:text-blue-600 transition-colors"
>首页</a
:class="[
'transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/') },
]"
@click.prevent="$router.push('/')"
>
首页
</a>
<a
href="#"
class="text-gray-600 hover:text-blue-600 transition-colors"
:class="[
'transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/product/') },
]"
@click.prevent="$router.push('/product/product')"
>购买商品</a
>
购买商品
</a>
<a
href="#"
class="text-gray-600 hover:text-blue-600 transition-colors"
:class="[
'transition-colors',
{
'text-blue-600 font-medium': isActiveRoute('/shoppingcart/'),
},
]"
@click.prevent="$router.push('/shoppingcart/content')"
>购物车</a
>
<!-- 移除我的订单链接 -->
购物车
</a>
<!-- 管理员导航项 -->
<a
v-if="isAdmin"
href="#"
class="text-gray-600 hover:text-blue-600 transition-colors"
:class="[
'transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/admin') },
]"
@click.prevent="goToAdmin"
>
管理界面
@@ -178,30 +210,51 @@ const goToProductManage = () => {
<div class="container mx-auto px-4 py-3 flex flex-col space-y-4">
<a
href="#"
class="py-2 text-gray-600 hover:text-blue-600 transition-colors"
>首页</a
:class="[
'py-2 transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/') },
]"
@click.prevent="$router.push('/')"
>
首页
</a>
<a
href="#"
class="py-2 text-gray-600 hover:text-blue-600 transition-colors"
:class="[
'py-2 transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/product/') },
]"
@click.prevent="$router.push('/product/product')"
>购买商品</a
>
购买商品
</a>
<a
href="#"
class="py-2 text-gray-600 hover:text-blue-600 transition-colors"
:class="[
'py-2 transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/shoppingcart/') },
]"
@click.prevent="$router.push('/shoppingcart/content')"
>购物车</a
>
购物车
</a>
<a
href="#"
class="py-2 text-gray-600 hover:text-blue-600 transition-colors"
>我的订单</a
:class="[
'py-2 transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/order/') },
]"
@click.prevent="$router.push('/order/content')"
>
我的订单
</a>
<a
v-if="isAdmin"
href="#"
class="py-2 text-gray-600 hover:text-blue-600 transition-colors"
:class="[
'py-2 transition-colors',
{ 'text-blue-600 font-medium': isActiveRoute('/admin') },
]"
@click.prevent="goToAdmin"
>
管理界面
@@ -211,27 +264,45 @@ const goToProductManage = () => {
<template v-if="isLoggedIn">
<div class="py-2 text-gray-700">欢迎{{ userNickname }}</div>
<button
:class="[
'w-full mb-2 px-4 py-2 text-left rounded-lg transition-colors',
{
'text-blue-600 bg-blue-50': isActiveRoute('/user/profile'),
},
]"
@click="goToProfile"
class="w-full mb-2 px-4 py-2 text-left text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
>
个人中心
</button>
<button
:class="[
'w-full mb-2 px-4 py-2 text-left rounded-lg transition-colors',
{
'text-blue-600 bg-blue-50': isActiveRoute('/user/product'),
},
]"
@click="goToProductManage"
class="w-full mb-2 px-4 py-2 text-left text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
>
我的商品
</button>
<button
:class="[
'w-full mb-2 px-4 py-2 text-left rounded-lg transition-colors',
{
'text-blue-600 bg-blue-50': isActiveRoute('/user/address'),
},
]"
@click="goToAddress"
class="w-full mb-2 px-4 py-2 text-left text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
>
我的地址
</button>
<button
v-if="isAdmin"
:class="[
'w-full mb-2 px-4 py-2 text-left rounded-lg transition-colors',
{ 'text-blue-600 bg-blue-50': isActiveRoute('/admin') },
]"
@click="goToAdmin"
class="w-full mb-2 px-4 py-2 text-left text-blue-600 hover:bg-blue-50 rounded-lg transition-colors"
>
管理界面
</button>

View File

@@ -55,7 +55,8 @@ const fetchProductList = async () => {
(product) => product.status === 1,
);
productList.value = activeProducts;
total.value = activeProducts.length;
// 使用API返回的总数量而不是过滤后的数量
total.value = response.data.total || 0;
} else {
productList.value = [];
total.value = 0;
@@ -287,19 +288,34 @@ onMounted(() => {
<!-- 搜索栏 -->
<div class="search-bar mb-8">
<div class="flex">
<div class="w-full">
<div class="relative">
<el-input
v-model="searchKeyword"
placeholder="搜索商品..."
class="flex-1"
class="search-input"
size="large"
@keyup.enter="handleSearch"
>
<template #prefix>
<el-icon class="el-input__icon">
<search />
</el-icon>
</template>
<template #append>
<el-button :icon="Search" @click="handleSearch" />
<el-button
class="search-button"
type="primary"
size="large"
@click="handleSearch"
>
搜索
</el-button>
</template>
</el-input>
</div>
</div>
</div>
<!-- 商品分类 -->
<div class="category-section mb-8">
@@ -569,6 +585,36 @@ onMounted(() => {
font-weight: normal;
}
/* 搜索框样式 */
.search-input {
border-radius: 50px;
}
.search-input :deep(.el-input__wrapper) {
border-radius: 50px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
padding-left: 20px;
width: 100%;
}
.search-input :deep(.el-input__prefix) {
display: flex;
align-items: center;
margin-right: 8px;
}
.search-input :deep(.el-input-group__append) {
border-radius: 50px;
margin-left: 8px; /* 增加间距 */
overflow: hidden;
}
.search-button {
border-radius: 50px;
padding: 0 30px;
font-weight: 500;
}
/* 滚动条样式 */
.category-container::-webkit-scrollbar {
width: 6px;